{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}

-----------------------------------------------------------------------------

-- |
-- Module      :  Distribution.Simple.Compiler
-- Copyright   :  Isaac Jones 2003-2004
-- License     :  BSD3
--
-- Maintainer  :  cabal-devel@haskell.org
-- Portability :  portable
--
-- This should be a much more sophisticated abstraction than it is. Currently
-- it's just a bit of data about the compiler, like its flavour and name and
-- version. The reason it's just data is because currently it has to be in
-- 'Read' and 'Show' so it can be saved along with the 'LocalBuildInfo'. The
-- only interesting bit of info it contains is a mapping between language
-- extensions and compiler command line flags. This module also defines a
-- 'PackageDB' type which is used to refer to package databases. Most compilers
-- only know about a single global package collection but GHC has a global and
-- per-user one and it lets you create arbitrary other package databases. We do
-- not yet fully support this latter feature.
module Distribution.Simple.Compiler
  ( -- * Haskell implementations
      module Distribution.Compiler
  , Compiler (..)
  , showCompilerId
  , showCompilerIdWithAbi
  , compilerFlavor
  , compilerVersion
  , compilerCompatFlavor
  , compilerCompatVersion
  , compilerInfo

    -- * Support for package databases
  , PackageDB
  , PackageDBStack
  , PackageDBCWD
  , PackageDBStackCWD
  , PackageDBX (..)
  , PackageDBStackX
  , PackageDBS
  , PackageDBStackS
  , registrationPackageDB
  , absolutePackageDBPaths
  , absolutePackageDBPath
  , interpretPackageDB
  , interpretPackageDBStack
  , coercePackageDB
  , coercePackageDBStack

    -- * Support for optimisation levels
  , OptimisationLevel (..)
  , flagToOptimisationLevel

    -- * Support for debug info levels
  , DebugInfoLevel (..)
  , flagToDebugInfoLevel

    -- * Support for language extensions
  , CompilerFlag
  , languageToFlags
  , unsupportedLanguages
  , extensionsToFlags
  , unsupportedExtensions
  , parmakeSupported
  , reexportedModulesSupported
  , renamingPackageFlagsSupported
  , unifiedIPIDRequired
  , packageKeySupported
  , unitIdSupported
  , coverageSupported
  , profilingSupported
  , profilingDynamicSupported
  , profilingDynamicSupportedOrUnknown
  , profilingVanillaSupported
  , profilingVanillaSupportedOrUnknown
  , dynamicSupported
  , backpackSupported
  , arResponseFilesSupported
  , arDashLSupported
  , libraryDynDirSupported
  , libraryVisibilitySupported
  , jsemSupported
  , reexportedAsSupported

    -- * Support for profiling detail levels
  , ProfDetailLevel (..)
  , knownProfDetailLevels
  , flagToProfDetailLevel
  , showProfDetailLevel
  ) where

import Distribution.Compat.Prelude
import Distribution.Pretty
import Prelude ()

import Distribution.Compiler
import Distribution.Simple.Utils
import Distribution.Utils.Path
import Distribution.Version

import Language.Haskell.Extension

import qualified Data.Map as Map (lookup)
import System.Directory (canonicalizePath)

data Compiler = Compiler
  { Compiler -> CompilerId
compilerId :: CompilerId
  -- ^ Compiler flavour and version.
  , Compiler -> AbiTag
compilerAbiTag :: AbiTag
  -- ^ Tag for distinguishing incompatible ABI's on the same
  -- architecture/os.
  , Compiler -> [CompilerId]
compilerCompat :: [CompilerId]
  -- ^ Other implementations that this compiler claims to be
  -- compatible with.
  , Compiler -> [(Language, [Char])]
compilerLanguages :: [(Language, CompilerFlag)]
  -- ^ Supported language standards.
  , Compiler -> [(Extension, Maybe [Char])]
compilerExtensions :: [(Extension, Maybe CompilerFlag)]
  -- ^ Supported extensions.
  , Compiler -> Map [Char] [Char]
compilerProperties :: Map String String
  -- ^ A key-value map for properties not covered by the above fields.
  }
  deriving (Compiler -> Compiler -> Bool
(Compiler -> Compiler -> Bool)
-> (Compiler -> Compiler -> Bool) -> Eq Compiler
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Compiler -> Compiler -> Bool
== :: Compiler -> Compiler -> Bool
$c/= :: Compiler -> Compiler -> Bool
/= :: Compiler -> Compiler -> Bool
Eq, (forall x. Compiler -> Rep Compiler x)
-> (forall x. Rep Compiler x -> Compiler) -> Generic Compiler
forall x. Rep Compiler x -> Compiler
forall x. Compiler -> Rep Compiler x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Compiler -> Rep Compiler x
from :: forall x. Compiler -> Rep Compiler x
$cto :: forall x. Rep Compiler x -> Compiler
to :: forall x. Rep Compiler x -> Compiler
Generic, Int -> Compiler -> ShowS
[Compiler] -> ShowS
Compiler -> [Char]
(Int -> Compiler -> ShowS)
-> (Compiler -> [Char]) -> ([Compiler] -> ShowS) -> Show Compiler
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Compiler -> ShowS
showsPrec :: Int -> Compiler -> ShowS
$cshow :: Compiler -> [Char]
show :: Compiler -> [Char]
$cshowList :: [Compiler] -> ShowS
showList :: [Compiler] -> ShowS
Show, ReadPrec [Compiler]
ReadPrec Compiler
Int -> ReadS Compiler
ReadS [Compiler]
(Int -> ReadS Compiler)
-> ReadS [Compiler]
-> ReadPrec Compiler
-> ReadPrec [Compiler]
-> Read Compiler
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Compiler
readsPrec :: Int -> ReadS Compiler
$creadList :: ReadS [Compiler]
readList :: ReadS [Compiler]
$creadPrec :: ReadPrec Compiler
readPrec :: ReadPrec Compiler
$creadListPrec :: ReadPrec [Compiler]
readListPrec :: ReadPrec [Compiler]
Read)

instance Binary Compiler
instance Structured Compiler

showCompilerId :: Compiler -> String
showCompilerId :: Compiler -> [Char]
showCompilerId = CompilerId -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow (CompilerId -> [Char])
-> (Compiler -> CompilerId) -> Compiler -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Compiler -> CompilerId
compilerId

showCompilerIdWithAbi :: Compiler -> String
showCompilerIdWithAbi :: Compiler -> [Char]
showCompilerIdWithAbi Compiler
comp =
  CompilerId -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow (Compiler -> CompilerId
compilerId Compiler
comp)
    [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ case Compiler -> AbiTag
compilerAbiTag Compiler
comp of
      AbiTag
NoAbiTag -> []
      AbiTag [Char]
xs -> Char
'-' Char -> ShowS
forall a. a -> [a] -> [a]
: [Char]
xs

compilerFlavor :: Compiler -> CompilerFlavor
compilerFlavor :: Compiler -> CompilerFlavor
compilerFlavor = (\(CompilerId CompilerFlavor
f Version
_) -> CompilerFlavor
f) (CompilerId -> CompilerFlavor)
-> (Compiler -> CompilerId) -> Compiler -> CompilerFlavor
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Compiler -> CompilerId
compilerId

compilerVersion :: Compiler -> Version
compilerVersion :: Compiler -> Version
compilerVersion = (\(CompilerId CompilerFlavor
_ Version
v) -> Version
v) (CompilerId -> Version)
-> (Compiler -> CompilerId) -> Compiler -> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Compiler -> CompilerId
compilerId

-- | Is this compiler compatible with the compiler flavour we're interested in?
--
-- For example this checks if the compiler is actually GHC or is another
-- compiler that claims to be compatible with some version of GHC, e.g. GHCJS.
--
-- > if compilerCompatFlavor GHC compiler then ... else ...
compilerCompatFlavor :: CompilerFlavor -> Compiler -> Bool
compilerCompatFlavor :: CompilerFlavor -> Compiler -> Bool
compilerCompatFlavor CompilerFlavor
flavor Compiler
comp =
  CompilerFlavor
flavor CompilerFlavor -> CompilerFlavor -> Bool
forall a. Eq a => a -> a -> Bool
== Compiler -> CompilerFlavor
compilerFlavor Compiler
comp
    Bool -> Bool -> Bool
|| CompilerFlavor
flavor CompilerFlavor -> [CompilerFlavor] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [CompilerFlavor
flavor' | CompilerId CompilerFlavor
flavor' Version
_ <- Compiler -> [CompilerId]
compilerCompat Compiler
comp]

-- | Is this compiler compatible with the compiler flavour we're interested in,
-- and if so what version does it claim to be compatible with.
--
-- For example this checks if the compiler is actually GHC-7.x or is another
-- compiler that claims to be compatible with some GHC-7.x version.
--
-- > case compilerCompatVersion GHC compiler of
-- >   Just (Version (7:_)) -> ...
-- >   _                    -> ...
compilerCompatVersion :: CompilerFlavor -> Compiler -> Maybe Version
compilerCompatVersion :: CompilerFlavor -> Compiler -> Maybe Version
compilerCompatVersion CompilerFlavor
flavor Compiler
comp
  | Compiler -> CompilerFlavor
compilerFlavor Compiler
comp CompilerFlavor -> CompilerFlavor -> Bool
forall a. Eq a => a -> a -> Bool
== CompilerFlavor
flavor = Version -> Maybe Version
forall a. a -> Maybe a
Just (Compiler -> Version
compilerVersion Compiler
comp)
  | Bool
otherwise =
      [Version] -> Maybe Version
forall a. [a] -> Maybe a
listToMaybe [Version
v | CompilerId CompilerFlavor
fl Version
v <- Compiler -> [CompilerId]
compilerCompat Compiler
comp, CompilerFlavor
fl CompilerFlavor -> CompilerFlavor -> Bool
forall a. Eq a => a -> a -> Bool
== CompilerFlavor
flavor]

compilerInfo :: Compiler -> CompilerInfo
compilerInfo :: Compiler -> CompilerInfo
compilerInfo Compiler
c =
  CompilerId
-> AbiTag
-> Maybe [CompilerId]
-> Maybe [Language]
-> Maybe [Extension]
-> CompilerInfo
CompilerInfo
    (Compiler -> CompilerId
compilerId Compiler
c)
    (Compiler -> AbiTag
compilerAbiTag Compiler
c)
    ([CompilerId] -> Maybe [CompilerId]
forall a. a -> Maybe a
Just ([CompilerId] -> Maybe [CompilerId])
-> (Compiler -> [CompilerId]) -> Compiler -> Maybe [CompilerId]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Compiler -> [CompilerId]
compilerCompat (Compiler -> Maybe [CompilerId]) -> Compiler -> Maybe [CompilerId]
forall a b. (a -> b) -> a -> b
$ Compiler
c)
    ([Language] -> Maybe [Language]
forall a. a -> Maybe a
Just ([Language] -> Maybe [Language])
-> (Compiler -> [Language]) -> Compiler -> Maybe [Language]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Language, [Char]) -> Language)
-> [(Language, [Char])] -> [Language]
forall a b. (a -> b) -> [a] -> [b]
map (Language, [Char]) -> Language
forall a b. (a, b) -> a
fst ([(Language, [Char])] -> [Language])
-> (Compiler -> [(Language, [Char])]) -> Compiler -> [Language]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Compiler -> [(Language, [Char])]
compilerLanguages (Compiler -> Maybe [Language]) -> Compiler -> Maybe [Language]
forall a b. (a -> b) -> a -> b
$ Compiler
c)
    ([Extension] -> Maybe [Extension]
forall a. a -> Maybe a
Just ([Extension] -> Maybe [Extension])
-> (Compiler -> [Extension]) -> Compiler -> Maybe [Extension]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Extension, Maybe [Char]) -> Extension)
-> [(Extension, Maybe [Char])] -> [Extension]
forall a b. (a -> b) -> [a] -> [b]
map (Extension, Maybe [Char]) -> Extension
forall a b. (a, b) -> a
fst ([(Extension, Maybe [Char])] -> [Extension])
-> (Compiler -> [(Extension, Maybe [Char])])
-> Compiler
-> [Extension]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Compiler -> [(Extension, Maybe [Char])]
compilerExtensions (Compiler -> Maybe [Extension]) -> Compiler -> Maybe [Extension]
forall a b. (a -> b) -> a -> b
$ Compiler
c)

-- ------------------------------------------------------------

-- * Package databases

-- ------------------------------------------------------------

-- | Some compilers have a notion of a database of available packages.
--  For some there is just one global db of packages, other compilers
--  support a per-user or an arbitrary db specified at some location in
--  the file system. This can be used to build isolated environments of
--  packages, for example to build a collection of related packages
--  without installing them globally.
--
--  Abstracted over
data PackageDBX fp
  = GlobalPackageDB
  | UserPackageDB
  | -- | NB: the path might be relative or it might be absolute
    SpecificPackageDB fp
  deriving (PackageDBX fp -> PackageDBX fp -> Bool
(PackageDBX fp -> PackageDBX fp -> Bool)
-> (PackageDBX fp -> PackageDBX fp -> Bool) -> Eq (PackageDBX fp)
forall fp. Eq fp => PackageDBX fp -> PackageDBX fp -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall fp. Eq fp => PackageDBX fp -> PackageDBX fp -> Bool
== :: PackageDBX fp -> PackageDBX fp -> Bool
$c/= :: forall fp. Eq fp => PackageDBX fp -> PackageDBX fp -> Bool
/= :: PackageDBX fp -> PackageDBX fp -> Bool
Eq, (forall x. PackageDBX fp -> Rep (PackageDBX fp) x)
-> (forall x. Rep (PackageDBX fp) x -> PackageDBX fp)
-> Generic (PackageDBX fp)
forall x. Rep (PackageDBX fp) x -> PackageDBX fp
forall x. PackageDBX fp -> Rep (PackageDBX fp) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall fp x. Rep (PackageDBX fp) x -> PackageDBX fp
forall fp x. PackageDBX fp -> Rep (PackageDBX fp) x
$cfrom :: forall fp x. PackageDBX fp -> Rep (PackageDBX fp) x
from :: forall x. PackageDBX fp -> Rep (PackageDBX fp) x
$cto :: forall fp x. Rep (PackageDBX fp) x -> PackageDBX fp
to :: forall x. Rep (PackageDBX fp) x -> PackageDBX fp
Generic, Eq (PackageDBX fp)
Eq (PackageDBX fp) =>
(PackageDBX fp -> PackageDBX fp -> Ordering)
-> (PackageDBX fp -> PackageDBX fp -> Bool)
-> (PackageDBX fp -> PackageDBX fp -> Bool)
-> (PackageDBX fp -> PackageDBX fp -> Bool)
-> (PackageDBX fp -> PackageDBX fp -> Bool)
-> (PackageDBX fp -> PackageDBX fp -> PackageDBX fp)
-> (PackageDBX fp -> PackageDBX fp -> PackageDBX fp)
-> Ord (PackageDBX fp)
PackageDBX fp -> PackageDBX fp -> Bool
PackageDBX fp -> PackageDBX fp -> Ordering
PackageDBX fp -> PackageDBX fp -> PackageDBX fp
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall fp. Ord fp => Eq (PackageDBX fp)
forall fp. Ord fp => PackageDBX fp -> PackageDBX fp -> Bool
forall fp. Ord fp => PackageDBX fp -> PackageDBX fp -> Ordering
forall fp.
Ord fp =>
PackageDBX fp -> PackageDBX fp -> PackageDBX fp
$ccompare :: forall fp. Ord fp => PackageDBX fp -> PackageDBX fp -> Ordering
compare :: PackageDBX fp -> PackageDBX fp -> Ordering
$c< :: forall fp. Ord fp => PackageDBX fp -> PackageDBX fp -> Bool
< :: PackageDBX fp -> PackageDBX fp -> Bool
$c<= :: forall fp. Ord fp => PackageDBX fp -> PackageDBX fp -> Bool
<= :: PackageDBX fp -> PackageDBX fp -> Bool
$c> :: forall fp. Ord fp => PackageDBX fp -> PackageDBX fp -> Bool
> :: PackageDBX fp -> PackageDBX fp -> Bool
$c>= :: forall fp. Ord fp => PackageDBX fp -> PackageDBX fp -> Bool
>= :: PackageDBX fp -> PackageDBX fp -> Bool
$cmax :: forall fp.
Ord fp =>
PackageDBX fp -> PackageDBX fp -> PackageDBX fp
max :: PackageDBX fp -> PackageDBX fp -> PackageDBX fp
$cmin :: forall fp.
Ord fp =>
PackageDBX fp -> PackageDBX fp -> PackageDBX fp
min :: PackageDBX fp -> PackageDBX fp -> PackageDBX fp
Ord, Int -> PackageDBX fp -> ShowS
[PackageDBX fp] -> ShowS
PackageDBX fp -> [Char]
(Int -> PackageDBX fp -> ShowS)
-> (PackageDBX fp -> [Char])
-> ([PackageDBX fp] -> ShowS)
-> Show (PackageDBX fp)
forall fp. Show fp => Int -> PackageDBX fp -> ShowS
forall fp. Show fp => [PackageDBX fp] -> ShowS
forall fp. Show fp => PackageDBX fp -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall fp. Show fp => Int -> PackageDBX fp -> ShowS
showsPrec :: Int -> PackageDBX fp -> ShowS
$cshow :: forall fp. Show fp => PackageDBX fp -> [Char]
show :: PackageDBX fp -> [Char]
$cshowList :: forall fp. Show fp => [PackageDBX fp] -> ShowS
showList :: [PackageDBX fp] -> ShowS
Show, ReadPrec [PackageDBX fp]
ReadPrec (PackageDBX fp)
Int -> ReadS (PackageDBX fp)
ReadS [PackageDBX fp]
(Int -> ReadS (PackageDBX fp))
-> ReadS [PackageDBX fp]
-> ReadPrec (PackageDBX fp)
-> ReadPrec [PackageDBX fp]
-> Read (PackageDBX fp)
forall fp. Read fp => ReadPrec [PackageDBX fp]
forall fp. Read fp => ReadPrec (PackageDBX fp)
forall fp. Read fp => Int -> ReadS (PackageDBX fp)
forall fp. Read fp => ReadS [PackageDBX fp]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall fp. Read fp => Int -> ReadS (PackageDBX fp)
readsPrec :: Int -> ReadS (PackageDBX fp)
$creadList :: forall fp. Read fp => ReadS [PackageDBX fp]
readList :: ReadS [PackageDBX fp]
$creadPrec :: forall fp. Read fp => ReadPrec (PackageDBX fp)
readPrec :: ReadPrec (PackageDBX fp)
$creadListPrec :: forall fp. Read fp => ReadPrec [PackageDBX fp]
readListPrec :: ReadPrec [PackageDBX fp]
Read, (forall a b. (a -> b) -> PackageDBX a -> PackageDBX b)
-> (forall a b. a -> PackageDBX b -> PackageDBX a)
-> Functor PackageDBX
forall a b. a -> PackageDBX b -> PackageDBX a
forall a b. (a -> b) -> PackageDBX a -> PackageDBX b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> PackageDBX a -> PackageDBX b
fmap :: forall a b. (a -> b) -> PackageDBX a -> PackageDBX b
$c<$ :: forall a b. a -> PackageDBX b -> PackageDBX a
<$ :: forall a b. a -> PackageDBX b -> PackageDBX a
Functor, (forall m. Monoid m => PackageDBX m -> m)
-> (forall m a. Monoid m => (a -> m) -> PackageDBX a -> m)
-> (forall m a. Monoid m => (a -> m) -> PackageDBX a -> m)
-> (forall a b. (a -> b -> b) -> b -> PackageDBX a -> b)
-> (forall a b. (a -> b -> b) -> b -> PackageDBX a -> b)
-> (forall b a. (b -> a -> b) -> b -> PackageDBX a -> b)
-> (forall b a. (b -> a -> b) -> b -> PackageDBX a -> b)
-> (forall a. (a -> a -> a) -> PackageDBX a -> a)
-> (forall a. (a -> a -> a) -> PackageDBX a -> a)
-> (forall a. PackageDBX a -> [a])
-> (forall a. PackageDBX a -> Bool)
-> (forall a. PackageDBX a -> Int)
-> (forall a. Eq a => a -> PackageDBX a -> Bool)
-> (forall a. Ord a => PackageDBX a -> a)
-> (forall a. Ord a => PackageDBX a -> a)
-> (forall a. Num a => PackageDBX a -> a)
-> (forall a. Num a => PackageDBX a -> a)
-> Foldable PackageDBX
forall a. Eq a => a -> PackageDBX a -> Bool
forall a. Num a => PackageDBX a -> a
forall a. Ord a => PackageDBX a -> a
forall m. Monoid m => PackageDBX m -> m
forall a. PackageDBX a -> Bool
forall a. PackageDBX a -> Int
forall a. PackageDBX a -> [a]
forall a. (a -> a -> a) -> PackageDBX a -> a
forall m a. Monoid m => (a -> m) -> PackageDBX a -> m
forall b a. (b -> a -> b) -> b -> PackageDBX a -> b
forall a b. (a -> b -> b) -> b -> PackageDBX a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => PackageDBX m -> m
fold :: forall m. Monoid m => PackageDBX m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> PackageDBX a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> PackageDBX a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> PackageDBX a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> PackageDBX a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> PackageDBX a -> b
foldr :: forall a b. (a -> b -> b) -> b -> PackageDBX a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> PackageDBX a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> PackageDBX a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> PackageDBX a -> b
foldl :: forall b a. (b -> a -> b) -> b -> PackageDBX a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> PackageDBX a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> PackageDBX a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> PackageDBX a -> a
foldr1 :: forall a. (a -> a -> a) -> PackageDBX a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> PackageDBX a -> a
foldl1 :: forall a. (a -> a -> a) -> PackageDBX a -> a
$ctoList :: forall a. PackageDBX a -> [a]
toList :: forall a. PackageDBX a -> [a]
$cnull :: forall a. PackageDBX a -> Bool
null :: forall a. PackageDBX a -> Bool
$clength :: forall a. PackageDBX a -> Int
length :: forall a. PackageDBX a -> Int
$celem :: forall a. Eq a => a -> PackageDBX a -> Bool
elem :: forall a. Eq a => a -> PackageDBX a -> Bool
$cmaximum :: forall a. Ord a => PackageDBX a -> a
maximum :: forall a. Ord a => PackageDBX a -> a
$cminimum :: forall a. Ord a => PackageDBX a -> a
minimum :: forall a. Ord a => PackageDBX a -> a
$csum :: forall a. Num a => PackageDBX a -> a
sum :: forall a. Num a => PackageDBX a -> a
$cproduct :: forall a. Num a => PackageDBX a -> a
product :: forall a. Num a => PackageDBX a -> a
Foldable, Functor PackageDBX
Foldable PackageDBX
(Functor PackageDBX, Foldable PackageDBX) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> PackageDBX a -> f (PackageDBX b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    PackageDBX (f a) -> f (PackageDBX a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> PackageDBX a -> m (PackageDBX b))
-> (forall (m :: * -> *) a.
    Monad m =>
    PackageDBX (m a) -> m (PackageDBX a))
-> Traversable PackageDBX
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
PackageDBX (m a) -> m (PackageDBX a)
forall (f :: * -> *) a.
Applicative f =>
PackageDBX (f a) -> f (PackageDBX a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> PackageDBX a -> m (PackageDBX b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> PackageDBX a -> f (PackageDBX b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> PackageDBX a -> f (PackageDBX b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> PackageDBX a -> f (PackageDBX b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
PackageDBX (f a) -> f (PackageDBX a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
PackageDBX (f a) -> f (PackageDBX a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> PackageDBX a -> m (PackageDBX b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> PackageDBX a -> m (PackageDBX b)
$csequence :: forall (m :: * -> *) a.
Monad m =>
PackageDBX (m a) -> m (PackageDBX a)
sequence :: forall (m :: * -> *) a.
Monad m =>
PackageDBX (m a) -> m (PackageDBX a)
Traversable)

instance Binary fp => Binary (PackageDBX fp)
instance Structured fp => Structured (PackageDBX fp)

-- | We typically get packages from several databases, and stack them
-- together. This type lets us be explicit about that stacking. For example
-- typical stacks include:
--
-- > [GlobalPackageDB]
-- > [GlobalPackageDB, UserPackageDB]
-- > [GlobalPackageDB, SpecificPackageDB "package.conf.inplace"]
--
-- Note that the 'GlobalPackageDB' is invariably at the bottom since it
-- contains the rts, base and other special compiler-specific packages.
--
-- We are not restricted to using just the above combinations. In particular
-- we can use several custom package dbs and the user package db together.
--
-- When it comes to writing, the top most (last) package is used.
type PackageDBStackX from = [PackageDBX from]

type PackageDB = PackageDBX (SymbolicPath Pkg (Dir PkgDB))
type PackageDBStack = PackageDBStackX (SymbolicPath Pkg (Dir PkgDB))

type PackageDBS from = PackageDBX (SymbolicPath from (Dir PkgDB))
type PackageDBStackS from = PackageDBStackX (SymbolicPath from (Dir PkgDB))

type PackageDBCWD = PackageDBX FilePath
type PackageDBStackCWD = PackageDBStackX FilePath

-- | Return the package that we should register into. This is the package db at
-- the top of the stack.
registrationPackageDB :: PackageDBStackX from -> PackageDBX from
registrationPackageDB :: forall from. PackageDBStackX from -> PackageDBX from
registrationPackageDB PackageDBStackX from
dbs = case PackageDBStackX from -> Maybe (PackageDBX from)
forall a. [a] -> Maybe a
safeLast PackageDBStackX from
dbs of
  Maybe (PackageDBX from)
Nothing -> [Char] -> PackageDBX from
forall a. HasCallStack => [Char] -> a
error [Char]
"internal error: empty package db set"
  Just PackageDBX from
p -> PackageDBX from
p

-- | Make package paths absolute
absolutePackageDBPaths
  :: Maybe (SymbolicPath CWD (Dir Pkg))
  -> PackageDBStack
  -> IO PackageDBStack
absolutePackageDBPaths :: Maybe (SymbolicPath CWD ('Dir Pkg))
-> PackageDBStack -> IO PackageDBStack
absolutePackageDBPaths Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir = (PackageDB -> IO PackageDB) -> PackageDBStack -> IO PackageDBStack
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((PackageDB -> IO PackageDB)
 -> PackageDBStack -> IO PackageDBStack)
-> (PackageDB -> IO PackageDB)
-> PackageDBStack
-> IO PackageDBStack
forall a b. (a -> b) -> a -> b
$ Maybe (SymbolicPath CWD ('Dir Pkg)) -> PackageDB -> IO PackageDB
absolutePackageDBPath Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir

absolutePackageDBPath
  :: Maybe (SymbolicPath CWD (Dir Pkg))
  -> PackageDB
  -> IO PackageDB
absolutePackageDBPath :: Maybe (SymbolicPath CWD ('Dir Pkg)) -> PackageDB -> IO PackageDB
absolutePackageDBPath Maybe (SymbolicPath CWD ('Dir Pkg))
_ PackageDB
GlobalPackageDB = PackageDB -> IO PackageDB
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PackageDB
forall fp. PackageDBX fp
GlobalPackageDB
absolutePackageDBPath Maybe (SymbolicPath CWD ('Dir Pkg))
_ PackageDB
UserPackageDB = PackageDB -> IO PackageDB
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PackageDB
forall fp. PackageDBX fp
UserPackageDB
absolutePackageDBPath Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir (SpecificPackageDB SymbolicPath Pkg ('Dir PkgDB)
db) = do
  let db' :: [Char]
db' =
        case SymbolicPath Pkg ('Dir PkgDB)
-> Maybe (RelativePath Pkg ('Dir PkgDB))
forall from (to :: FileOrDir).
SymbolicPath from to -> Maybe (RelativePath from to)
symbolicPathRelative_maybe SymbolicPath Pkg ('Dir PkgDB)
db of
          Maybe (RelativePath Pkg ('Dir PkgDB))
Nothing -> SymbolicPath Pkg ('Dir PkgDB) -> [Char]
forall (allowAbsolute :: AllowAbsolute) from (to :: FileOrDir).
SymbolicPathX allowAbsolute from to -> [Char]
getSymbolicPath SymbolicPath Pkg ('Dir PkgDB)
db
          Just RelativePath Pkg ('Dir PkgDB)
rel_path -> Maybe (SymbolicPath CWD ('Dir Pkg))
-> RelativePath Pkg ('Dir PkgDB) -> [Char]
forall from (allowAbsolute :: AllowAbsolute) (to :: FileOrDir).
Maybe (SymbolicPath CWD ('Dir from))
-> SymbolicPathX allowAbsolute from to -> [Char]
interpretSymbolicPath Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir RelativePath Pkg ('Dir PkgDB)
rel_path
  SymbolicPath Pkg ('Dir PkgDB) -> PackageDB
forall fp. fp -> PackageDBX fp
SpecificPackageDB (SymbolicPath Pkg ('Dir PkgDB) -> PackageDB)
-> ([Char] -> SymbolicPath Pkg ('Dir PkgDB)) -> [Char] -> PackageDB
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> SymbolicPath Pkg ('Dir PkgDB)
forall from (to :: FileOrDir). [Char] -> SymbolicPath from to
makeSymbolicPath ([Char] -> PackageDB) -> IO [Char] -> IO PackageDB
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> IO [Char]
canonicalizePath [Char]
db'

interpretPackageDB :: Maybe (SymbolicPath CWD (Dir Pkg)) -> PackageDB -> PackageDBCWD
interpretPackageDB :: Maybe (SymbolicPath CWD ('Dir Pkg)) -> PackageDB -> PackageDBCWD
interpretPackageDB Maybe (SymbolicPath CWD ('Dir Pkg))
_ PackageDB
GlobalPackageDB = PackageDBCWD
forall fp. PackageDBX fp
GlobalPackageDB
interpretPackageDB Maybe (SymbolicPath CWD ('Dir Pkg))
_ PackageDB
UserPackageDB = PackageDBCWD
forall fp. PackageDBX fp
UserPackageDB
interpretPackageDB Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir (SpecificPackageDB SymbolicPath Pkg ('Dir PkgDB)
db) =
  [Char] -> PackageDBCWD
forall fp. fp -> PackageDBX fp
SpecificPackageDB (Maybe (SymbolicPath CWD ('Dir Pkg))
-> SymbolicPath Pkg ('Dir PkgDB) -> [Char]
forall from (allowAbsolute :: AllowAbsolute) (to :: FileOrDir).
Maybe (SymbolicPath CWD ('Dir from))
-> SymbolicPathX allowAbsolute from to -> [Char]
interpretSymbolicPath Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir SymbolicPath Pkg ('Dir PkgDB)
db)

interpretPackageDBStack :: Maybe (SymbolicPath CWD (Dir Pkg)) -> PackageDBStack -> PackageDBStackCWD
interpretPackageDBStack :: Maybe (SymbolicPath CWD ('Dir Pkg))
-> PackageDBStack -> PackageDBStackCWD
interpretPackageDBStack Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir = (PackageDB -> PackageDBCWD) -> PackageDBStack -> PackageDBStackCWD
forall a b. (a -> b) -> [a] -> [b]
map (Maybe (SymbolicPath CWD ('Dir Pkg)) -> PackageDB -> PackageDBCWD
interpretPackageDB Maybe (SymbolicPath CWD ('Dir Pkg))
mbWorkDir)

-- | Transform a package db using a FilePath into one using symbolic paths.
coercePackageDB :: PackageDBCWD -> PackageDBX (SymbolicPath CWD (Dir PkgDB))
coercePackageDB :: PackageDBCWD -> PackageDBX (SymbolicPath CWD ('Dir PkgDB))
coercePackageDB PackageDBCWD
GlobalPackageDB = PackageDBX (SymbolicPath CWD ('Dir PkgDB))
forall fp. PackageDBX fp
GlobalPackageDB
coercePackageDB PackageDBCWD
UserPackageDB = PackageDBX (SymbolicPath CWD ('Dir PkgDB))
forall fp. PackageDBX fp
UserPackageDB
coercePackageDB (SpecificPackageDB [Char]
db) = SymbolicPath CWD ('Dir PkgDB)
-> PackageDBX (SymbolicPath CWD ('Dir PkgDB))
forall fp. fp -> PackageDBX fp
SpecificPackageDB ([Char] -> SymbolicPath CWD ('Dir PkgDB)
forall from (to :: FileOrDir). [Char] -> SymbolicPath from to
makeSymbolicPath [Char]
db)

coercePackageDBStack
  :: [PackageDBCWD]
  -> [PackageDBX (SymbolicPath CWD (Dir PkgDB))]
coercePackageDBStack :: PackageDBStackCWD -> [PackageDBX (SymbolicPath CWD ('Dir PkgDB))]
coercePackageDBStack = (PackageDBCWD -> PackageDBX (SymbolicPath CWD ('Dir PkgDB)))
-> PackageDBStackCWD
-> [PackageDBX (SymbolicPath CWD ('Dir PkgDB))]
forall a b. (a -> b) -> [a] -> [b]
map PackageDBCWD -> PackageDBX (SymbolicPath CWD ('Dir PkgDB))
coercePackageDB

-- ------------------------------------------------------------

-- * Optimisation levels

-- ------------------------------------------------------------

-- | Some compilers support optimising. Some have different levels.
-- For compilers that do not the level is just capped to the level
-- they do support.
data OptimisationLevel
  = NoOptimisation
  | NormalOptimisation
  | MaximumOptimisation
  deriving (OptimisationLevel
OptimisationLevel -> OptimisationLevel -> Bounded OptimisationLevel
forall a. a -> a -> Bounded a
$cminBound :: OptimisationLevel
minBound :: OptimisationLevel
$cmaxBound :: OptimisationLevel
maxBound :: OptimisationLevel
Bounded, Int -> OptimisationLevel
OptimisationLevel -> Int
OptimisationLevel -> [OptimisationLevel]
OptimisationLevel -> OptimisationLevel
OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
OptimisationLevel
-> OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
(OptimisationLevel -> OptimisationLevel)
-> (OptimisationLevel -> OptimisationLevel)
-> (Int -> OptimisationLevel)
-> (OptimisationLevel -> Int)
-> (OptimisationLevel -> [OptimisationLevel])
-> (OptimisationLevel -> OptimisationLevel -> [OptimisationLevel])
-> (OptimisationLevel -> OptimisationLevel -> [OptimisationLevel])
-> (OptimisationLevel
    -> OptimisationLevel -> OptimisationLevel -> [OptimisationLevel])
-> Enum OptimisationLevel
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: OptimisationLevel -> OptimisationLevel
succ :: OptimisationLevel -> OptimisationLevel
$cpred :: OptimisationLevel -> OptimisationLevel
pred :: OptimisationLevel -> OptimisationLevel
$ctoEnum :: Int -> OptimisationLevel
toEnum :: Int -> OptimisationLevel
$cfromEnum :: OptimisationLevel -> Int
fromEnum :: OptimisationLevel -> Int
$cenumFrom :: OptimisationLevel -> [OptimisationLevel]
enumFrom :: OptimisationLevel -> [OptimisationLevel]
$cenumFromThen :: OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
enumFromThen :: OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
$cenumFromTo :: OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
enumFromTo :: OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
$cenumFromThenTo :: OptimisationLevel
-> OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
enumFromThenTo :: OptimisationLevel
-> OptimisationLevel -> OptimisationLevel -> [OptimisationLevel]
Enum, OptimisationLevel -> OptimisationLevel -> Bool
(OptimisationLevel -> OptimisationLevel -> Bool)
-> (OptimisationLevel -> OptimisationLevel -> Bool)
-> Eq OptimisationLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: OptimisationLevel -> OptimisationLevel -> Bool
== :: OptimisationLevel -> OptimisationLevel -> Bool
$c/= :: OptimisationLevel -> OptimisationLevel -> Bool
/= :: OptimisationLevel -> OptimisationLevel -> Bool
Eq, (forall x. OptimisationLevel -> Rep OptimisationLevel x)
-> (forall x. Rep OptimisationLevel x -> OptimisationLevel)
-> Generic OptimisationLevel
forall x. Rep OptimisationLevel x -> OptimisationLevel
forall x. OptimisationLevel -> Rep OptimisationLevel x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. OptimisationLevel -> Rep OptimisationLevel x
from :: forall x. OptimisationLevel -> Rep OptimisationLevel x
$cto :: forall x. Rep OptimisationLevel x -> OptimisationLevel
to :: forall x. Rep OptimisationLevel x -> OptimisationLevel
Generic, ReadPrec [OptimisationLevel]
ReadPrec OptimisationLevel
Int -> ReadS OptimisationLevel
ReadS [OptimisationLevel]
(Int -> ReadS OptimisationLevel)
-> ReadS [OptimisationLevel]
-> ReadPrec OptimisationLevel
-> ReadPrec [OptimisationLevel]
-> Read OptimisationLevel
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS OptimisationLevel
readsPrec :: Int -> ReadS OptimisationLevel
$creadList :: ReadS [OptimisationLevel]
readList :: ReadS [OptimisationLevel]
$creadPrec :: ReadPrec OptimisationLevel
readPrec :: ReadPrec OptimisationLevel
$creadListPrec :: ReadPrec [OptimisationLevel]
readListPrec :: ReadPrec [OptimisationLevel]
Read, Int -> OptimisationLevel -> ShowS
[OptimisationLevel] -> ShowS
OptimisationLevel -> [Char]
(Int -> OptimisationLevel -> ShowS)
-> (OptimisationLevel -> [Char])
-> ([OptimisationLevel] -> ShowS)
-> Show OptimisationLevel
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> OptimisationLevel -> ShowS
showsPrec :: Int -> OptimisationLevel -> ShowS
$cshow :: OptimisationLevel -> [Char]
show :: OptimisationLevel -> [Char]
$cshowList :: [OptimisationLevel] -> ShowS
showList :: [OptimisationLevel] -> ShowS
Show)

instance Binary OptimisationLevel
instance Structured OptimisationLevel

flagToOptimisationLevel :: Maybe String -> OptimisationLevel
flagToOptimisationLevel :: Maybe [Char] -> OptimisationLevel
flagToOptimisationLevel Maybe [Char]
Nothing = OptimisationLevel
NormalOptimisation
flagToOptimisationLevel (Just [Char]
s) = case ReadS Int
forall a. Read a => ReadS a
reads [Char]
s of
  [(Int
i, [Char]
"")]
    | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= OptimisationLevel -> Int
forall a. Enum a => a -> Int
fromEnum (OptimisationLevel
forall a. Bounded a => a
minBound :: OptimisationLevel)
        Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= OptimisationLevel -> Int
forall a. Enum a => a -> Int
fromEnum (OptimisationLevel
forall a. Bounded a => a
maxBound :: OptimisationLevel) ->
        Int -> OptimisationLevel
forall a. Enum a => Int -> a
toEnum Int
i
    | Bool
otherwise ->
        [Char] -> OptimisationLevel
forall a. HasCallStack => [Char] -> a
error ([Char] -> OptimisationLevel) -> [Char] -> OptimisationLevel
forall a b. (a -> b) -> a -> b
$
          [Char]
"Bad optimisation level: "
            [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
            [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
". Valid values are 0..2"
  [(Int, [Char])]
_ -> [Char] -> OptimisationLevel
forall a. HasCallStack => [Char] -> a
error ([Char] -> OptimisationLevel) -> [Char] -> OptimisationLevel
forall a b. (a -> b) -> a -> b
$ [Char]
"Can't parse optimisation level " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
s

-- ------------------------------------------------------------

-- * Debug info levels

-- ------------------------------------------------------------

-- | Some compilers support emitting debug info. Some have different
-- levels.  For compilers that do not the level is just capped to the
-- level they do support.
data DebugInfoLevel
  = NoDebugInfo
  | MinimalDebugInfo
  | NormalDebugInfo
  | MaximalDebugInfo
  deriving (DebugInfoLevel
DebugInfoLevel -> DebugInfoLevel -> Bounded DebugInfoLevel
forall a. a -> a -> Bounded a
$cminBound :: DebugInfoLevel
minBound :: DebugInfoLevel
$cmaxBound :: DebugInfoLevel
maxBound :: DebugInfoLevel
Bounded, Int -> DebugInfoLevel
DebugInfoLevel -> Int
DebugInfoLevel -> [DebugInfoLevel]
DebugInfoLevel -> DebugInfoLevel
DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
DebugInfoLevel
-> DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
(DebugInfoLevel -> DebugInfoLevel)
-> (DebugInfoLevel -> DebugInfoLevel)
-> (Int -> DebugInfoLevel)
-> (DebugInfoLevel -> Int)
-> (DebugInfoLevel -> [DebugInfoLevel])
-> (DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel])
-> (DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel])
-> (DebugInfoLevel
    -> DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel])
-> Enum DebugInfoLevel
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: DebugInfoLevel -> DebugInfoLevel
succ :: DebugInfoLevel -> DebugInfoLevel
$cpred :: DebugInfoLevel -> DebugInfoLevel
pred :: DebugInfoLevel -> DebugInfoLevel
$ctoEnum :: Int -> DebugInfoLevel
toEnum :: Int -> DebugInfoLevel
$cfromEnum :: DebugInfoLevel -> Int
fromEnum :: DebugInfoLevel -> Int
$cenumFrom :: DebugInfoLevel -> [DebugInfoLevel]
enumFrom :: DebugInfoLevel -> [DebugInfoLevel]
$cenumFromThen :: DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
enumFromThen :: DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
$cenumFromTo :: DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
enumFromTo :: DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
$cenumFromThenTo :: DebugInfoLevel
-> DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
enumFromThenTo :: DebugInfoLevel
-> DebugInfoLevel -> DebugInfoLevel -> [DebugInfoLevel]
Enum, DebugInfoLevel -> DebugInfoLevel -> Bool
(DebugInfoLevel -> DebugInfoLevel -> Bool)
-> (DebugInfoLevel -> DebugInfoLevel -> Bool) -> Eq DebugInfoLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DebugInfoLevel -> DebugInfoLevel -> Bool
== :: DebugInfoLevel -> DebugInfoLevel -> Bool
$c/= :: DebugInfoLevel -> DebugInfoLevel -> Bool
/= :: DebugInfoLevel -> DebugInfoLevel -> Bool
Eq, (forall x. DebugInfoLevel -> Rep DebugInfoLevel x)
-> (forall x. Rep DebugInfoLevel x -> DebugInfoLevel)
-> Generic DebugInfoLevel
forall x. Rep DebugInfoLevel x -> DebugInfoLevel
forall x. DebugInfoLevel -> Rep DebugInfoLevel x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DebugInfoLevel -> Rep DebugInfoLevel x
from :: forall x. DebugInfoLevel -> Rep DebugInfoLevel x
$cto :: forall x. Rep DebugInfoLevel x -> DebugInfoLevel
to :: forall x. Rep DebugInfoLevel x -> DebugInfoLevel
Generic, ReadPrec [DebugInfoLevel]
ReadPrec DebugInfoLevel
Int -> ReadS DebugInfoLevel
ReadS [DebugInfoLevel]
(Int -> ReadS DebugInfoLevel)
-> ReadS [DebugInfoLevel]
-> ReadPrec DebugInfoLevel
-> ReadPrec [DebugInfoLevel]
-> Read DebugInfoLevel
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DebugInfoLevel
readsPrec :: Int -> ReadS DebugInfoLevel
$creadList :: ReadS [DebugInfoLevel]
readList :: ReadS [DebugInfoLevel]
$creadPrec :: ReadPrec DebugInfoLevel
readPrec :: ReadPrec DebugInfoLevel
$creadListPrec :: ReadPrec [DebugInfoLevel]
readListPrec :: ReadPrec [DebugInfoLevel]
Read, Int -> DebugInfoLevel -> ShowS
[DebugInfoLevel] -> ShowS
DebugInfoLevel -> [Char]
(Int -> DebugInfoLevel -> ShowS)
-> (DebugInfoLevel -> [Char])
-> ([DebugInfoLevel] -> ShowS)
-> Show DebugInfoLevel
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DebugInfoLevel -> ShowS
showsPrec :: Int -> DebugInfoLevel -> ShowS
$cshow :: DebugInfoLevel -> [Char]
show :: DebugInfoLevel -> [Char]
$cshowList :: [DebugInfoLevel] -> ShowS
showList :: [DebugInfoLevel] -> ShowS
Show)

instance Binary DebugInfoLevel
instance Structured DebugInfoLevel

flagToDebugInfoLevel :: Maybe String -> DebugInfoLevel
flagToDebugInfoLevel :: Maybe [Char] -> DebugInfoLevel
flagToDebugInfoLevel Maybe [Char]
Nothing = DebugInfoLevel
NormalDebugInfo
flagToDebugInfoLevel (Just [Char]
s) = case ReadS Int
forall a. Read a => ReadS a
reads [Char]
s of
  [(Int
i, [Char]
"")]
    | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= DebugInfoLevel -> Int
forall a. Enum a => a -> Int
fromEnum (DebugInfoLevel
forall a. Bounded a => a
minBound :: DebugInfoLevel)
        Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= DebugInfoLevel -> Int
forall a. Enum a => a -> Int
fromEnum (DebugInfoLevel
forall a. Bounded a => a
maxBound :: DebugInfoLevel) ->
        Int -> DebugInfoLevel
forall a. Enum a => Int -> a
toEnum Int
i
    | Bool
otherwise ->
        [Char] -> DebugInfoLevel
forall a. HasCallStack => [Char] -> a
error ([Char] -> DebugInfoLevel) -> [Char] -> DebugInfoLevel
forall a b. (a -> b) -> a -> b
$
          [Char]
"Bad debug info level: "
            [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
            [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
". Valid values are 0..3"
  [(Int, [Char])]
_ -> [Char] -> DebugInfoLevel
forall a. HasCallStack => [Char] -> a
error ([Char] -> DebugInfoLevel) -> [Char] -> DebugInfoLevel
forall a b. (a -> b) -> a -> b
$ [Char]
"Can't parse debug info level " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
s

-- ------------------------------------------------------------

-- * Languages and Extensions

-- ------------------------------------------------------------

unsupportedLanguages :: Compiler -> [Language] -> [Language]
unsupportedLanguages :: Compiler -> [Language] -> [Language]
unsupportedLanguages Compiler
comp [Language]
langs =
  [ Language
lang | Language
lang <- [Language]
langs, Maybe [Char] -> Bool
forall a. Maybe a -> Bool
isNothing (Compiler -> Language -> Maybe [Char]
languageToFlag Compiler
comp Language
lang)
  ]

languageToFlags :: Compiler -> Maybe Language -> [CompilerFlag]
languageToFlags :: Compiler -> Maybe Language -> [[Char]]
languageToFlags Compiler
comp =
  ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> ([Char] -> Bool) -> [Char] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null)
    ([[Char]] -> [[Char]])
-> (Maybe Language -> [[Char]]) -> Maybe Language -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe [Char]] -> [[Char]]
forall a. [Maybe a] -> [a]
catMaybes
    ([Maybe [Char]] -> [[Char]])
-> (Maybe Language -> [Maybe [Char]]) -> Maybe Language -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Language -> Maybe [Char]) -> [Language] -> [Maybe [Char]]
forall a b. (a -> b) -> [a] -> [b]
map (Compiler -> Language -> Maybe [Char]
languageToFlag Compiler
comp)
    ([Language] -> [Maybe [Char]])
-> (Maybe Language -> [Language])
-> Maybe Language
-> [Maybe [Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Language]
-> (Language -> [Language]) -> Maybe Language -> [Language]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Language
Haskell98] (\Language
x -> [Language
x])

languageToFlag :: Compiler -> Language -> Maybe CompilerFlag
languageToFlag :: Compiler -> Language -> Maybe [Char]
languageToFlag Compiler
comp Language
ext = Language -> [(Language, [Char])] -> Maybe [Char]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Language
ext (Compiler -> [(Language, [Char])]
compilerLanguages Compiler
comp)

-- | For the given compiler, return the extensions it does not support.
unsupportedExtensions :: Compiler -> [Extension] -> [Extension]
unsupportedExtensions :: Compiler -> [Extension] -> [Extension]
unsupportedExtensions Compiler
comp [Extension]
exts =
  [ Extension
ext | Extension
ext <- [Extension]
exts, Maybe (Maybe [Char]) -> Bool
forall a. Maybe a -> Bool
isNothing (Compiler -> Extension -> Maybe (Maybe [Char])
extensionToFlag' Compiler
comp Extension
ext)
  ]

type CompilerFlag = String

-- | For the given compiler, return the flags for the supported extensions.
extensionsToFlags :: Compiler -> [Extension] -> [CompilerFlag]
extensionsToFlags :: Compiler -> [Extension] -> [[Char]]
extensionsToFlags Compiler
comp =
  [[Char]] -> [[Char]]
forall a. Eq a => [a] -> [a]
nub
    ([[Char]] -> [[Char]])
-> ([Extension] -> [[Char]]) -> [Extension] -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> ([Char] -> Bool) -> [Char] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null)
    ([[Char]] -> [[Char]])
-> ([Extension] -> [[Char]]) -> [Extension] -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe [Char]] -> [[Char]]
forall a. [Maybe a] -> [a]
catMaybes
    ([Maybe [Char]] -> [[Char]])
-> ([Extension] -> [Maybe [Char]]) -> [Extension] -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Extension -> Maybe [Char]) -> [Extension] -> [Maybe [Char]]
forall a b. (a -> b) -> [a] -> [b]
map (Compiler -> Extension -> Maybe [Char]
extensionToFlag Compiler
comp)

-- | Looks up the flag for a given extension, for a given compiler.
-- Ignores the subtlety of extensions which lack associated flags.
extensionToFlag :: Compiler -> Extension -> Maybe CompilerFlag
extensionToFlag :: Compiler -> Extension -> Maybe [Char]
extensionToFlag Compiler
comp Extension
ext = Maybe (Maybe [Char]) -> Maybe [Char]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Compiler -> Extension -> Maybe (Maybe [Char])
extensionToFlag' Compiler
comp Extension
ext)

-- | Looks up the flag for a given extension, for a given compiler.
-- However, the extension may be valid for the compiler but not have a flag.
-- For example, NondecreasingIndentation is enabled by default on GHC 7.0.4,
-- hence it is considered a supported extension but not an accepted flag.
--
-- The outer layer of Maybe indicates whether the extensions is supported, while
-- the inner layer indicates whether it has a flag.
-- When building strings, it is often more convenient to use 'extensionToFlag',
-- which ignores the difference.
extensionToFlag' :: Compiler -> Extension -> Maybe (Maybe CompilerFlag)
extensionToFlag' :: Compiler -> Extension -> Maybe (Maybe [Char])
extensionToFlag' Compiler
comp Extension
ext = Extension -> [(Extension, Maybe [Char])] -> Maybe (Maybe [Char])
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Extension
ext (Compiler -> [(Extension, Maybe [Char])]
compilerExtensions Compiler
comp)

-- | Does this compiler support parallel --make mode?
parmakeSupported :: Compiler -> Bool
parmakeSupported :: Compiler -> Bool
parmakeSupported = [Char] -> Compiler -> Bool
ghcSupported [Char]
"Support parallel --make"

-- | Does this compiler support reexported-modules?
reexportedModulesSupported :: Compiler -> Bool
reexportedModulesSupported :: Compiler -> Bool
reexportedModulesSupported = [Char] -> Compiler -> Bool
ghcSupported [Char]
"Support reexported-modules"

-- | Does this compiler support thinning/renaming on package flags?
renamingPackageFlagsSupported :: Compiler -> Bool
renamingPackageFlagsSupported :: Compiler -> Bool
renamingPackageFlagsSupported =
  [Char] -> Compiler -> Bool
ghcSupported
    [Char]
"Support thinning and renaming package flags"

-- | Does this compiler have unified IPIDs (so no package keys)
unifiedIPIDRequired :: Compiler -> Bool
unifiedIPIDRequired :: Compiler -> Bool
unifiedIPIDRequired = [Char] -> Compiler -> Bool
ghcSupported [Char]
"Requires unified installed package IDs"

-- | Does this compiler support package keys?
packageKeySupported :: Compiler -> Bool
packageKeySupported :: Compiler -> Bool
packageKeySupported = [Char] -> Compiler -> Bool
ghcSupported [Char]
"Uses package keys"

-- | Does this compiler support unit IDs?
unitIdSupported :: Compiler -> Bool
unitIdSupported :: Compiler -> Bool
unitIdSupported = [Char] -> Compiler -> Bool
ghcSupported [Char]
"Uses unit IDs"

-- | Does this compiler support Backpack?
backpackSupported :: Compiler -> Bool
backpackSupported :: Compiler -> Bool
backpackSupported = [Char] -> Compiler -> Bool
ghcSupported [Char]
"Support Backpack"

-- | Does this compiler support the -jsem option?
jsemSupported :: Compiler -> Bool
jsemSupported :: Compiler -> Bool
jsemSupported Compiler
comp = case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
  CompilerFlavor
GHC -> Version
v Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
mkVersion [Int
9, Int
7]
  CompilerFlavor
_ -> Bool
False
  where
    v :: Version
v = Compiler -> Version
compilerVersion Compiler
comp

-- | Does the compiler support the -reexported-modules "A as B" syntax
reexportedAsSupported :: Compiler -> Bool
reexportedAsSupported :: Compiler -> Bool
reexportedAsSupported Compiler
comp = case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
  CompilerFlavor
GHC -> Version
v Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
mkVersion [Int
9, Int
12]
  CompilerFlavor
_ -> Bool
False
  where
    v :: Version
v = Compiler -> Version
compilerVersion Compiler
comp

-- | Does this compiler support a package database entry with:
-- "dynamic-library-dirs"?
libraryDynDirSupported :: Compiler -> Bool
libraryDynDirSupported :: Compiler -> Bool
libraryDynDirSupported Compiler
comp = case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
  CompilerFlavor
GHC ->
    -- Not just v >= mkVersion [8,0,1,20161022], as there
    -- are many GHC 8.1 nightlies which don't support this.
    ( (Version
v Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
mkVersion [Int
8, Int
0, Int
1, Int
20161022] Bool -> Bool -> Bool
&& Version
v Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
< [Int] -> Version
mkVersion [Int
8, Int
1])
        Bool -> Bool -> Bool
|| Version
v Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
mkVersion [Int
8, Int
1, Int
20161021]
    )
  CompilerFlavor
_ -> Bool
False
  where
    v :: Version
v = Compiler -> Version
compilerVersion Compiler
comp

-- | Does this compiler's "ar" command supports response file
-- arguments (i.e. @file-style arguments).
arResponseFilesSupported :: Compiler -> Bool
arResponseFilesSupported :: Compiler -> Bool
arResponseFilesSupported = [Char] -> Compiler -> Bool
ghcSupported [Char]
"ar supports at file"

-- | Does this compiler's "ar" command support llvm-ar's -L flag,
-- which compels the archiver to add an input archive's members
-- rather than adding the archive itself.
arDashLSupported :: Compiler -> Bool
arDashLSupported :: Compiler -> Bool
arDashLSupported = [Char] -> Compiler -> Bool
ghcSupported [Char]
"ar supports -L"

-- | Does this compiler support Haskell program coverage?
coverageSupported :: Compiler -> Bool
coverageSupported :: Compiler -> Bool
coverageSupported Compiler
comp =
  case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
    CompilerFlavor
GHC -> Bool
True
    CompilerFlavor
GHCJS -> Bool
True
    CompilerFlavor
_ -> Bool
False

-- | Does this compiler support profiling?
profilingSupported :: Compiler -> Bool
profilingSupported :: Compiler -> Bool
profilingSupported Compiler
comp =
  case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
    CompilerFlavor
GHC -> Bool
True
    CompilerFlavor
GHCJS -> Bool
True
    CompilerFlavor
_ -> Bool
False

-- | Returns Just if we can certainly determine whether a way is supported
-- if we don't know, return Nothing
waySupported :: String -> Compiler -> Maybe Bool
waySupported :: [Char] -> Compiler -> Maybe Bool
waySupported [Char]
way Compiler
comp =
  case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
    CompilerFlavor
GHC ->
      -- Information about compiler ways is only accurately reported after
      -- 9.10.1. Which is useful as this is before profiling dynamic support
      -- was introduced. (See GHC #24881)
      if Compiler -> Version
compilerVersion Compiler
comp Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
mkVersion [Int
9, Int
10, Int
1]
        then case [Char] -> Map [Char] [Char] -> Maybe [Char]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup [Char]
"RTS ways" (Compiler -> Map [Char] [Char]
compilerProperties Compiler
comp) of
          Just [Char]
ways -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just ([Char]
way [Char] -> [[Char]] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char] -> [[Char]]
words [Char]
ways)
          Maybe [Char]
Nothing -> Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
        else Maybe Bool
forall a. Maybe a
Nothing
    CompilerFlavor
_ -> Maybe Bool
forall a. Maybe a
Nothing

-- | Either profiling is definitely supported or we don't know (so assume
-- it is)
profilingVanillaSupportedOrUnknown :: Compiler -> Bool
profilingVanillaSupportedOrUnknown :: Compiler -> Bool
profilingVanillaSupportedOrUnknown Compiler
comp = Compiler -> Maybe Bool
profilingVanillaSupported Compiler
comp Maybe Bool -> [Maybe Bool] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True, Maybe Bool
forall a. Maybe a
Nothing]

-- | Is the compiler distributed with profiling libraries
profilingVanillaSupported :: Compiler -> Maybe Bool
profilingVanillaSupported :: Compiler -> Maybe Bool
profilingVanillaSupported Compiler
comp = [Char] -> Compiler -> Maybe Bool
waySupported [Char]
"p" Compiler
comp

-- | Is the compiler distributed with profiling dynamic libraries
profilingDynamicSupported :: Compiler -> Maybe Bool
profilingDynamicSupported :: Compiler -> Maybe Bool
profilingDynamicSupported Compiler
comp
  | CompilerFlavor
GHC <- Compiler -> CompilerFlavor
compilerFlavor Compiler
comp
  , -- Certainly not before 9.11, as prof+dyn was not implemented yet.
    Compiler -> Version
compilerVersion Compiler
comp Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
<= [Int] -> Version
mkVersion [Int
9, Int
11, Int
0] =
      Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
  | Bool
otherwise =
      [Char] -> Compiler -> Maybe Bool
waySupported [Char]
"p_dyn" Compiler
comp

-- | Either profiling dynamic is definitely supported or we don't know (so assume
-- it is)
profilingDynamicSupportedOrUnknown :: Compiler -> Bool
profilingDynamicSupportedOrUnknown :: Compiler -> Bool
profilingDynamicSupportedOrUnknown Compiler
comp =
  Compiler -> Maybe Bool
profilingDynamicSupported Compiler
comp Maybe Bool -> [Maybe Bool] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True, Maybe Bool
forall a. Maybe a
Nothing]

-- | Is the compiler distributed with dynamic libraries
dynamicSupported :: Compiler -> Maybe Bool
dynamicSupported :: Compiler -> Maybe Bool
dynamicSupported Compiler
comp = [Char] -> Compiler -> Maybe Bool
waySupported [Char]
"dyn" Compiler
comp

-- | Does this compiler support a package database entry with:
-- "visibility"?
libraryVisibilitySupported :: Compiler -> Bool
libraryVisibilitySupported :: Compiler -> Bool
libraryVisibilitySupported Compiler
comp = case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
  CompilerFlavor
GHC -> Version
v Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
mkVersion [Int
8, Int
8]
  CompilerFlavor
_ -> Bool
False
  where
    v :: Version
v = Compiler -> Version
compilerVersion Compiler
comp

-- | Utility function for GHC only features
ghcSupported :: String -> Compiler -> Bool
ghcSupported :: [Char] -> Compiler -> Bool
ghcSupported [Char]
key Compiler
comp =
  case Compiler -> CompilerFlavor
compilerFlavor Compiler
comp of
    CompilerFlavor
GHC -> Bool
checkProp
    CompilerFlavor
GHCJS -> Bool
checkProp
    CompilerFlavor
_ -> Bool
False
  where
    checkProp :: Bool
checkProp =
      case [Char] -> Map [Char] [Char] -> Maybe [Char]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup [Char]
key (Compiler -> Map [Char] [Char]
compilerProperties Compiler
comp) of
        Just [Char]
"YES" -> Bool
True
        Maybe [Char]
_ -> Bool
False

-- ------------------------------------------------------------

-- * Profiling detail level

-- ------------------------------------------------------------

-- | Some compilers (notably GHC) support profiling and can instrument
-- programs so the system can account costs to different functions. There are
-- different levels of detail that can be used for this accounting.
-- For compilers that do not support this notion or the particular detail
-- levels, this is either ignored or just capped to some similar level
-- they do support.
data ProfDetailLevel
  = ProfDetailNone
  | ProfDetailDefault
  | ProfDetailExportedFunctions
  | ProfDetailToplevelFunctions
  | ProfDetailAllFunctions
  | ProfDetailTopLate
  | ProfDetailOther String
  deriving (ProfDetailLevel -> ProfDetailLevel -> Bool
(ProfDetailLevel -> ProfDetailLevel -> Bool)
-> (ProfDetailLevel -> ProfDetailLevel -> Bool)
-> Eq ProfDetailLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProfDetailLevel -> ProfDetailLevel -> Bool
== :: ProfDetailLevel -> ProfDetailLevel -> Bool
$c/= :: ProfDetailLevel -> ProfDetailLevel -> Bool
/= :: ProfDetailLevel -> ProfDetailLevel -> Bool
Eq, (forall x. ProfDetailLevel -> Rep ProfDetailLevel x)
-> (forall x. Rep ProfDetailLevel x -> ProfDetailLevel)
-> Generic ProfDetailLevel
forall x. Rep ProfDetailLevel x -> ProfDetailLevel
forall x. ProfDetailLevel -> Rep ProfDetailLevel x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ProfDetailLevel -> Rep ProfDetailLevel x
from :: forall x. ProfDetailLevel -> Rep ProfDetailLevel x
$cto :: forall x. Rep ProfDetailLevel x -> ProfDetailLevel
to :: forall x. Rep ProfDetailLevel x -> ProfDetailLevel
Generic, ReadPrec [ProfDetailLevel]
ReadPrec ProfDetailLevel
Int -> ReadS ProfDetailLevel
ReadS [ProfDetailLevel]
(Int -> ReadS ProfDetailLevel)
-> ReadS [ProfDetailLevel]
-> ReadPrec ProfDetailLevel
-> ReadPrec [ProfDetailLevel]
-> Read ProfDetailLevel
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS ProfDetailLevel
readsPrec :: Int -> ReadS ProfDetailLevel
$creadList :: ReadS [ProfDetailLevel]
readList :: ReadS [ProfDetailLevel]
$creadPrec :: ReadPrec ProfDetailLevel
readPrec :: ReadPrec ProfDetailLevel
$creadListPrec :: ReadPrec [ProfDetailLevel]
readListPrec :: ReadPrec [ProfDetailLevel]
Read, Int -> ProfDetailLevel -> ShowS
[ProfDetailLevel] -> ShowS
ProfDetailLevel -> [Char]
(Int -> ProfDetailLevel -> ShowS)
-> (ProfDetailLevel -> [Char])
-> ([ProfDetailLevel] -> ShowS)
-> Show ProfDetailLevel
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ProfDetailLevel -> ShowS
showsPrec :: Int -> ProfDetailLevel -> ShowS
$cshow :: ProfDetailLevel -> [Char]
show :: ProfDetailLevel -> [Char]
$cshowList :: [ProfDetailLevel] -> ShowS
showList :: [ProfDetailLevel] -> ShowS
Show)

instance Binary ProfDetailLevel
instance Structured ProfDetailLevel

flagToProfDetailLevel :: String -> ProfDetailLevel
flagToProfDetailLevel :: [Char] -> ProfDetailLevel
flagToProfDetailLevel [Char]
"" = ProfDetailLevel
ProfDetailDefault
flagToProfDetailLevel [Char]
s =
  case [Char] -> [([Char], ProfDetailLevel)] -> Maybe ProfDetailLevel
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup
    (ShowS
lowercase [Char]
s)
    [ ([Char]
name, ProfDetailLevel
value)
    | ([Char]
primary, [[Char]]
aliases, ProfDetailLevel
value) <- [([Char], [[Char]], ProfDetailLevel)]
knownProfDetailLevels
    , [Char]
name <- [Char]
primary [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [[Char]]
aliases
    ] of
    Just ProfDetailLevel
value -> ProfDetailLevel
value
    Maybe ProfDetailLevel
Nothing -> [Char] -> ProfDetailLevel
ProfDetailOther [Char]
s

knownProfDetailLevels :: [(String, [String], ProfDetailLevel)]
knownProfDetailLevels :: [([Char], [[Char]], ProfDetailLevel)]
knownProfDetailLevels =
  [ ([Char]
"default", [], ProfDetailLevel
ProfDetailDefault)
  , ([Char]
"none", [], ProfDetailLevel
ProfDetailNone)
  , ([Char]
"exported-functions", [[Char]
"exported"], ProfDetailLevel
ProfDetailExportedFunctions)
  , ([Char]
"toplevel-functions", [[Char]
"toplevel", [Char]
"top"], ProfDetailLevel
ProfDetailToplevelFunctions)
  , ([Char]
"all-functions", [[Char]
"all"], ProfDetailLevel
ProfDetailAllFunctions)
  , ([Char]
"late-toplevel", [[Char]
"late"], ProfDetailLevel
ProfDetailTopLate)
  ]

showProfDetailLevel :: ProfDetailLevel -> String
showProfDetailLevel :: ProfDetailLevel -> [Char]
showProfDetailLevel ProfDetailLevel
dl = case ProfDetailLevel
dl of
  ProfDetailLevel
ProfDetailNone -> [Char]
"none"
  ProfDetailLevel
ProfDetailDefault -> [Char]
"default"
  ProfDetailLevel
ProfDetailExportedFunctions -> [Char]
"exported-functions"
  ProfDetailLevel
ProfDetailToplevelFunctions -> [Char]
"toplevel-functions"
  ProfDetailLevel
ProfDetailAllFunctions -> [Char]
"all-functions"
  ProfDetailLevel
ProfDetailTopLate -> [Char]
"late-toplevel"
  ProfDetailOther [Char]
other -> [Char]
other