<commit_before>{-# LANGUAGE DeriveGeneric #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.Compiler
-- Copyright   :  <NAME> 2003-2004
-- License     :  BSD3
--
-- Maintainer  :  <EMAIL>
-- 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 it's 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,
        compilerCompatVersion,
        compilerInfo,

        -- * Support for package databases
        PackageDB(..),
        PackageDBStack,
        registrationPackageDB,
        absolutePackageDBPaths,
        absolutePackageDBPath,

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

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

        -- * Support for language extensions
        Flag,
        languageToFlags,
        unsupportedLanguages,
        extensionsToFlags,
        unsupportedExtensions,
        parmakeSupported,
        reexportedModulesSupported,
        renamingPackageFlagsSupported,
        unifiedIPIDRequired,
        packageKeySupported,
        unitIdSupported,

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

import Distribution.Compiler
import Distribution.Version
import Distribution.Text
import Language.Haskell.Extension
import Distribution.Simple.Utils
import Distribution.Compat.Binary

import Control.Monad (liftM)
import Data.List (nub)
import qualified Data.Map as M (Map, lookup)
import Data.Maybe (catMaybes, isNothing, listToMaybe)
import GHC.Generics (Generic)
import System.Directory (canonicalizePath)

data Compiler = Compiler {
        compilerId              :: CompilerId,
        -- ^ Compiler flavour and version.
        compilerAbiTag          :: AbiTag,
        -- ^ Tag for distinguishing incompatible ABI's on the same architecture/os.
        compilerCompat          :: [CompilerId],
        -- ^ Other implementations that this compiler claims to be compatible with.
        compilerLanguages       :: [(Language, Flag)],
        -- ^ Supported language standards.
        compilerExtensions      :: [(Extension, Flag)],
        -- ^ Supported extensions.
        compilerProperties      :: M.Map String String
        -- ^ A key-value map for properties not covered by the above fields.
    }
    deriving (Eq, Generic, Show, Read)

instance Binary Compiler

showCompilerId :: Compiler -> String
showCompilerId = display . compilerId

showCompilerIdWithAbi :: Compiler -> String
showCompilerIdWithAbi comp =
  display (compilerId comp) ++
  case compilerAbiTag comp of
    NoAbiTag  -> []
    AbiTag xs -> '-':xs

compilerFlavor ::  Compiler -> CompilerFlavor
compilerFlavor = (\(CompilerId f _) -> f) . compilerId

compilerVersion :: Compiler -> Version
compilerVersion = (\(CompilerId _ v) -> v) . compilerId

compilerCompatVersion :: CompilerFlavor -> Compiler -> Maybe Version
compilerCompatVersion flavor comp
  | compilerFlavor comp == flavor = Just (compilerVersion comp)
  | otherwise    =
      listToMaybe [ v | CompilerId fl v <- compilerCompat comp, fl == flavor ]

compilerInfo :: Compiler -> CompilerInfo
compilerInfo c = CompilerInfo (compilerId c)
                              (compilerAbiTag c)
                              (Just . compilerCompat $ c)
                              (Just . map fst . compilerLanguages $ c)
                              (Just . map fst . compilerExtensions $ c)

-- ------------------------------------------------------------
-- * Package databases
-- ------------------------------------------------------------
<commit_msg>Add util compilerCompatFlavor, and document compilerCompatVersion<commit_after>{-# LANGUAGE DeriveGeneric #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.Compiler
-- Copyright   :  <NAME> 2003-2004
-- License     :  BSD3
--
-- Maintainer  :  <EMAIL>
-- 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 it's 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,
        registrationPackageDB,
        absolutePackageDBPaths,
        absolutePackageDBPath,

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

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

        -- * Support for language extensions
        Flag,
        languageToFlags,
        unsupportedLanguages,
        extensionsToFlags,
        unsupportedExtensions,
        parmakeSupported,
        reexportedModulesSupported,
        renamingPackageFlagsSupported,
        unifiedIPIDRequired,
        packageKeySupported,
        unitIdSupported,

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

import Distribution.Compiler
import Distribution.Version
import Distribution.Text
import Language.Haskell.Extension
import Distribution.Simple.Utils
import Distribution.Compat.Binary

import Control.Monad (liftM)
import Data.List (nub)
import qualified Data.Map as M (Map, lookup)
import Data.Maybe (catMaybes, isNothing, listToMaybe)
import GHC.Generics (Generic)
import System.Directory (canonicalizePath)

data Compiler = Compiler {
        compilerId              :: CompilerId,
        -- ^ Compiler flavour and version.
        compilerAbiTag          :: AbiTag,
        -- ^ Tag for distinguishing incompatible ABI's on the same architecture/os.
        compilerCompat          :: [CompilerId],
        -- ^ Other implementations that this compiler claims to be compatible with.
        compilerLanguages       :: [(Language, Flag)],
        -- ^ Supported language standards.
        compilerExtensions      :: [(Extension, Flag)],
        -- ^ Supported extensions.
        compilerProperties      :: M.Map String String
        -- ^ A key-value map for properties not covered by the above fields.
    }
    deriving (Eq, Generic, Show, Read)

instance Binary Compiler

showCompilerId :: Compiler -> String
showCompilerId = display . compilerId

showCompilerIdWithAbi :: Compiler -> String
showCompilerIdWithAbi comp =
  display (compilerId comp) ++
  case compilerAbiTag comp of
    NoAbiTag  -> []
    AbiTag xs -> '-':xs

compilerFlavor ::  Compiler -> CompilerFlavor
compilerFlavor = (\(CompilerId f _) -> f) . compilerId

compilerVersion :: Compiler -> Version
compilerVersion = (\(CompilerId _ v) -> v) . 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 flavor comp =
    flavor == compilerFlavor comp
 || flavor `elem` [ flavor' | CompilerId flavor' _ <- compilerCompat 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 flavor comp
  | compilerFlavor comp == flavor = Just (compilerVersion comp)
  | otherwise    =
      listToMaybe [ v | CompilerId fl v <- compilerCompat comp, fl == flavor ]

compilerInfo :: Compiler -> CompilerInfo
compilerInfo c = CompilerInfo (compilerId c)
                              (compilerAbiTag c)
                              (Just . compilerCompat $ c)
                              (Just . map fst . compilerLanguages $ c)
                              (Just . map fst . compilerExtensions $ c)

-- ------------------------------------------------------------
-- * Package databases
-- ------------------------------------------------------------

{'fraction_non_alphanumeric': 0.11588149587178243, 'fraction_numerical': 0.0020398251578436135, 'mean_word_length': 2.2387543252595155, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5984818', 'n_tokens_mistral': 2552, 'n_tokens_neox': 2453, 'n_words': 892}