{-# LANGUAGE CPP #-}

-----------------------------------------------------------------------------
--
-- GHC Driver
--
-- (c) The University of Glasgow 2002
--
-----------------------------------------------------------------------------

module GHC.Driver.Phases (
   HscSource(..), isHsBootOrSig, isHsigFile, hscSourceString,
   Phase(..),
   happensBefore, eqPhase, anyHsc, isStopLn,
   startPhase,
   phaseInputExt,

   isHaskellishSuffix,
   isHaskellSrcSuffix,
   isBackpackishSuffix,
   isObjectSuffix,
   isCishSuffix,
   isDynLibSuffix,
   isHaskellUserSrcSuffix,
   isHaskellSigSuffix,
   isSourceSuffix,

   isHaskellishTarget,

   isHaskellishFilename,
   isHaskellSrcFilename,
   isHaskellSigFilename,
   isObjectFilename,
   isCishFilename,
   isDynLibFilename,
   isHaskellUserSrcFilename,
   isSourceFilename
 ) where

#include "HsVersions.h"

import GHC.Prelude

import GHC.Utils.Outputable
import GHC.Platform
import System.FilePath
import GHC.Utils.Binary
import GHC.Utils.Misc

-----------------------------------------------------------------------------
-- Phases

{-
   Phase of the           | Suffix saying | Flag saying   | (suffix of)
   compilation system     | ``start here''| ``stop after''| output file

   literate pre-processor | .lhs          | -             | -
   C pre-processor (opt.) | -             | -E            | -
   Haskell compiler       | .hs           | -C, -S        | .hc, .s
   C compiler (opt.)      | .hc or .c     | -S            | .s
   assembler              | .s  or .S     | -c            | .o
   linker                 | other         | -             | a.out
-}

-- Note [HscSource types]
-- ~~~~~~~~~~~~~~~~~~~~~~
-- There are three types of source file for Haskell code:
--
--      * HsSrcFile is an ordinary hs file which contains code,
--
--      * HsBootFile is an hs-boot file, which is used to break
--        recursive module imports (there will always be an
--        HsSrcFile associated with it), and
--
--      * HsigFile is an hsig file, which contains only type
--        signatures and is used to specify signatures for
--        modules.
--
-- Syntactically, hs-boot files and hsig files are quite similar: they
-- only include type signatures and must be associated with an
-- actual HsSrcFile.  isHsBootOrSig allows us to abstract over code
-- which is indifferent to which.  However, there are some important
-- differences, mostly owing to the fact that hsigs are proper
-- modules (you `import Sig` directly) whereas HsBootFiles are
-- temporary placeholders (you `import {-# SOURCE #-} Mod).
-- When we finish compiling the true implementation of an hs-boot,
-- we replace the HomeModInfo with the real HsSrcFile.  An HsigFile, on the
-- other hand, is never replaced (in particular, we *cannot* use the
-- HomeModInfo of the original HsSrcFile backing the signature, since it
-- will export too many symbols.)
--
-- Additionally, while HsSrcFile is the only Haskell file
-- which has *code*, we do generate .o files for HsigFile, because
-- this is how the recompilation checker figures out if a file
-- needs to be recompiled.  These are fake object files which
-- should NOT be linked against.

data HscSource
   = HsSrcFile | HsBootFile | HsigFile
     deriving( HscSource -> HscSource -> Bool
(HscSource -> HscSource -> Bool)
-> (HscSource -> HscSource -> Bool) -> Eq HscSource
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HscSource -> HscSource -> Bool
$c/= :: HscSource -> HscSource -> Bool
== :: HscSource -> HscSource -> Bool
$c== :: HscSource -> HscSource -> Bool
Eq, Eq HscSource
Eq HscSource
-> (HscSource -> HscSource -> Ordering)
-> (HscSource -> HscSource -> Bool)
-> (HscSource -> HscSource -> Bool)
-> (HscSource -> HscSource -> Bool)
-> (HscSource -> HscSource -> Bool)
-> (HscSource -> HscSource -> HscSource)
-> (HscSource -> HscSource -> HscSource)
-> Ord HscSource
HscSource -> HscSource -> Bool
HscSource -> HscSource -> Ordering
HscSource -> HscSource -> HscSource
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
min :: HscSource -> HscSource -> HscSource
$cmin :: HscSource -> HscSource -> HscSource
max :: HscSource -> HscSource -> HscSource
$cmax :: HscSource -> HscSource -> HscSource
>= :: HscSource -> HscSource -> Bool
$c>= :: HscSource -> HscSource -> Bool
> :: HscSource -> HscSource -> Bool
$c> :: HscSource -> HscSource -> Bool
<= :: HscSource -> HscSource -> Bool
$c<= :: HscSource -> HscSource -> Bool
< :: HscSource -> HscSource -> Bool
$c< :: HscSource -> HscSource -> Bool
compare :: HscSource -> HscSource -> Ordering
$ccompare :: HscSource -> HscSource -> Ordering
Ord, Int -> HscSource -> ShowS
[HscSource] -> ShowS
HscSource -> String
(Int -> HscSource -> ShowS)
-> (HscSource -> String)
-> ([HscSource] -> ShowS)
-> Show HscSource
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HscSource] -> ShowS
$cshowList :: [HscSource] -> ShowS
show :: HscSource -> String
$cshow :: HscSource -> String
showsPrec :: Int -> HscSource -> ShowS
$cshowsPrec :: Int -> HscSource -> ShowS
Show )
        -- Ord needed for the finite maps we build in CompManager

instance Binary HscSource where
    put_ :: BinHandle -> HscSource -> IO ()
put_ BinHandle
bh HscSource
HsSrcFile = BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
    put_ BinHandle
bh HscSource
HsBootFile = BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
    put_ BinHandle
bh HscSource
HsigFile = BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
2
    get :: BinHandle -> IO HscSource
get BinHandle
bh = do
        Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
        case Word8
h of
            Word8
0 -> HscSource -> IO HscSource
forall (m :: * -> *) a. Monad m => a -> m a
return HscSource
HsSrcFile
            Word8
1 -> HscSource -> IO HscSource
forall (m :: * -> *) a. Monad m => a -> m a
return HscSource
HsBootFile
            Word8
_ -> HscSource -> IO HscSource
forall (m :: * -> *) a. Monad m => a -> m a
return HscSource
HsigFile

hscSourceString :: HscSource -> String
hscSourceString :: HscSource -> String
hscSourceString HscSource
HsSrcFile   = String
""
hscSourceString HscSource
HsBootFile  = String
"[boot]"
hscSourceString HscSource
HsigFile    = String
"[sig]"

-- See Note [isHsBootOrSig]
isHsBootOrSig :: HscSource -> Bool
isHsBootOrSig :: HscSource -> Bool
isHsBootOrSig HscSource
HsBootFile = Bool
True
isHsBootOrSig HscSource
HsigFile   = Bool
True
isHsBootOrSig HscSource
_          = Bool
False

isHsigFile :: HscSource -> Bool
isHsigFile :: HscSource -> Bool
isHsigFile HscSource
HsigFile = Bool
True
isHsigFile HscSource
_        = Bool
False

data Phase
        = Unlit HscSource
        | Cpp   HscSource
        | HsPp  HscSource
        | Hsc   HscSource
        | Ccxx          -- Compile C++
        | Cc            -- Compile C
        | Cobjc         -- Compile Objective-C
        | Cobjcxx       -- Compile Objective-C++
        | HCc           -- Haskellised C (as opposed to vanilla C) compilation
        | As Bool       -- Assembler for regular assembly files (Bool: with-cpp)
        | LlvmOpt       -- Run LLVM opt tool over llvm assembly
        | LlvmLlc       -- LLVM bitcode to native assembly
        | LlvmMangle    -- Fix up TNTC by processing assembly produced by LLVM
        | CmmCpp        -- pre-process Cmm source
        | Cmm           -- parse & compile Cmm code
        | MergeForeign  -- merge in the foreign object files

        -- The final phase is a pseudo-phase that tells the pipeline to stop.
        -- There is no runPhase case for it.
        | StopLn        -- Stop, but linking will follow, so generate .o file
  deriving (Phase -> Phase -> Bool
(Phase -> Phase -> Bool) -> (Phase -> Phase -> Bool) -> Eq Phase
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Phase -> Phase -> Bool
$c/= :: Phase -> Phase -> Bool
== :: Phase -> Phase -> Bool
$c== :: Phase -> Phase -> Bool
Eq, Int -> Phase -> ShowS
[Phase] -> ShowS
Phase -> String
(Int -> Phase -> ShowS)
-> (Phase -> String) -> ([Phase] -> ShowS) -> Show Phase
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Phase] -> ShowS
$cshowList :: [Phase] -> ShowS
show :: Phase -> String
$cshow :: Phase -> String
showsPrec :: Int -> Phase -> ShowS
$cshowsPrec :: Int -> Phase -> ShowS
Show)

instance Outputable Phase where
    ppr :: Phase -> SDoc
ppr Phase
p = String -> SDoc
text (Phase -> String
forall a. Show a => a -> String
show Phase
p)

anyHsc :: Phase
anyHsc :: Phase
anyHsc = HscSource -> Phase
Hsc (String -> HscSource
forall a. String -> a
panic String
"anyHsc")

isStopLn :: Phase -> Bool
isStopLn :: Phase -> Bool
isStopLn Phase
StopLn = Bool
True
isStopLn Phase
_      = Bool
False

eqPhase :: Phase -> Phase -> Bool
-- Equality of constructors, ignoring the HscSource field
-- NB: the HscSource field can be 'bot'; see anyHsc above
eqPhase :: Phase -> Phase -> Bool
eqPhase (Unlit HscSource
_)   (Unlit HscSource
_)  = Bool
True
eqPhase (Cpp   HscSource
_)   (Cpp   HscSource
_)  = Bool
True
eqPhase (HsPp  HscSource
_)   (HsPp  HscSource
_)  = Bool
True
eqPhase (Hsc   HscSource
_)   (Hsc   HscSource
_)  = Bool
True
eqPhase Phase
Cc          Phase
Cc         = Bool
True
eqPhase Phase
Cobjc       Phase
Cobjc      = Bool
True
eqPhase Phase
HCc         Phase
HCc        = Bool
True
eqPhase (As Bool
x)      (As Bool
y)     = Bool
x Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
y
eqPhase Phase
LlvmOpt     Phase
LlvmOpt    = Bool
True
eqPhase Phase
LlvmLlc     Phase
LlvmLlc    = Bool
True
eqPhase Phase
LlvmMangle  Phase
LlvmMangle = Bool
True
eqPhase Phase
CmmCpp      Phase
CmmCpp     = Bool
True
eqPhase Phase
Cmm         Phase
Cmm        = Bool
True
eqPhase Phase
MergeForeign Phase
MergeForeign  = Bool
True
eqPhase Phase
StopLn      Phase
StopLn     = Bool
True
eqPhase Phase
Ccxx        Phase
Ccxx       = Bool
True
eqPhase Phase
Cobjcxx     Phase
Cobjcxx    = Bool
True
eqPhase Phase
_           Phase
_          = Bool
False

{- Note [Partial ordering on phases]

We want to know which phases will occur before which others. This is used for
sanity checking, to ensure that the pipeline will stop at some point (see
GHC.Driver.Pipeline.runPipeline).

A < B iff A occurs before B in a normal compilation pipeline.

There is explicitly not a total ordering on phases, because in registerised
builds, the phase `HsC` doesn't happen before nor after any other phase.

Although we check that a normal user doesn't set the stop_phase to HsC through
use of -C with registerised builds (in Main.checkOptions), it is still
possible for a ghc-api user to do so. So be careful when using the function
happensBefore, and don't think that `not (a <= b)` implies `b < a`.
-}
happensBefore :: Platform -> Phase -> Phase -> Bool
happensBefore :: Platform -> Phase -> Phase -> Bool
happensBefore Platform
platform Phase
p1 Phase
p2 = Phase
p1 Phase -> Phase -> Bool
`happensBefore'` Phase
p2
    where Phase
StopLn happensBefore' :: Phase -> Phase -> Bool
`happensBefore'` Phase
_ = Bool
False
          Phase
x      `happensBefore'` Phase
y = Phase
after_x Phase -> Phase -> Bool
`eqPhase` Phase
y
                                   Bool -> Bool -> Bool
|| Phase
after_x Phase -> Phase -> Bool
`happensBefore'` Phase
y
              where after_x :: Phase
after_x = Platform -> Phase -> Phase
nextPhase Platform
platform Phase
x

nextPhase :: Platform -> Phase -> Phase
nextPhase :: Platform -> Phase -> Phase
nextPhase Platform
platform Phase
p
    -- A conservative approximation to the next phase, used in happensBefore
    = case Phase
p of
      Unlit HscSource
sf   -> HscSource -> Phase
Cpp  HscSource
sf
      Cpp   HscSource
sf   -> HscSource -> Phase
HsPp HscSource
sf
      HsPp  HscSource
sf   -> HscSource -> Phase
Hsc  HscSource
sf
      Hsc   HscSource
_    -> Phase
maybeHCc
      Phase
LlvmOpt    -> Phase
LlvmLlc
      Phase
LlvmLlc    -> Phase
LlvmMangle
      Phase
LlvmMangle -> Bool -> Phase
As Bool
False
      As Bool
_       -> Phase
MergeForeign
      Phase
Ccxx       -> Bool -> Phase
As Bool
False
      Phase
Cc         -> Bool -> Phase
As Bool
False
      Phase
Cobjc      -> Bool -> Phase
As Bool
False
      Phase
Cobjcxx    -> Bool -> Phase
As Bool
False
      Phase
CmmCpp     -> Phase
Cmm
      Phase
Cmm        -> Phase
maybeHCc
      Phase
HCc        -> Bool -> Phase
As Bool
False
      Phase
MergeForeign -> Phase
StopLn
      Phase
StopLn     -> String -> Phase
forall a. String -> a
panic String
"nextPhase: nothing after StopLn"
    where maybeHCc :: Phase
maybeHCc = if Platform -> Bool
platformUnregisterised Platform
platform
                     then Phase
HCc
                     else Bool -> Phase
As Bool
False

-- the first compilation phase for a given file is determined
-- by its suffix.
startPhase :: String -> Phase
startPhase :: String -> Phase
startPhase String
"lhs"      = HscSource -> Phase
Unlit HscSource
HsSrcFile
startPhase String
"lhs-boot" = HscSource -> Phase
Unlit HscSource
HsBootFile
startPhase String
"lhsig"    = HscSource -> Phase
Unlit HscSource
HsigFile
startPhase String
"hs"       = HscSource -> Phase
Cpp   HscSource
HsSrcFile
startPhase String
"hs-boot"  = HscSource -> Phase
Cpp   HscSource
HsBootFile
startPhase String
"hsig"     = HscSource -> Phase
Cpp   HscSource
HsigFile
startPhase String
"hscpp"    = HscSource -> Phase
HsPp  HscSource
HsSrcFile
startPhase String
"hspp"     = HscSource -> Phase
Hsc   HscSource
HsSrcFile
startPhase String
"hc"       = Phase
HCc
startPhase String
"c"        = Phase
Cc
startPhase String
"cpp"      = Phase
Ccxx
startPhase String
"C"        = Phase
Cc
startPhase String
"m"        = Phase
Cobjc
startPhase String
"M"        = Phase
Cobjcxx
startPhase String
"mm"       = Phase
Cobjcxx
startPhase String
"cc"       = Phase
Ccxx
startPhase String
"cxx"      = Phase
Ccxx
startPhase String
"s"        = Bool -> Phase
As Bool
False
startPhase String
"S"        = Bool -> Phase
As Bool
True
startPhase String
"ll"       = Phase
LlvmOpt
startPhase String
"bc"       = Phase
LlvmLlc
startPhase String
"lm_s"     = Phase
LlvmMangle
startPhase String
"o"        = Phase
StopLn
startPhase String
"cmm"      = Phase
CmmCpp
startPhase String
"cmmcpp"   = Phase
Cmm
startPhase String
_          = Phase
StopLn     -- all unknown file types

-- This is used to determine the extension for the output from the
-- current phase (if it generates a new file).  The extension depends
-- on the next phase in the pipeline.
phaseInputExt :: Phase -> String
phaseInputExt :: Phase -> String
phaseInputExt (Unlit HscSource
HsSrcFile)   = String
"lhs"
phaseInputExt (Unlit HscSource
HsBootFile)  = String
"lhs-boot"
phaseInputExt (Unlit HscSource
HsigFile)    = String
"lhsig"
phaseInputExt (Cpp   HscSource
_)           = String
"lpp"       -- intermediate only
phaseInputExt (HsPp  HscSource
_)           = String
"hscpp"     -- intermediate only
phaseInputExt (Hsc   HscSource
_)           = String
"hspp"      -- intermediate only
        -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
        --     because runPipeline uses the StopBefore phase to pick the
        --     output filename.  That could be fixed, but watch out.
phaseInputExt Phase
HCc                 = String
"hc"
phaseInputExt Phase
Ccxx                = String
"cpp"
phaseInputExt Phase
Cobjc               = String
"m"
phaseInputExt Phase
Cobjcxx             = String
"mm"
phaseInputExt Phase
Cc                  = String
"c"
phaseInputExt (As Bool
True)           = String
"S"
phaseInputExt (As Bool
False)          = String
"s"
phaseInputExt Phase
LlvmOpt             = String
"ll"
phaseInputExt Phase
LlvmLlc             = String
"bc"
phaseInputExt Phase
LlvmMangle          = String
"lm_s"
phaseInputExt Phase
CmmCpp              = String
"cmmcpp"
phaseInputExt Phase
Cmm                 = String
"cmm"
phaseInputExt Phase
MergeForeign        = String
"o"
phaseInputExt Phase
StopLn              = String
"o"

haskellish_src_suffixes, backpackish_suffixes, haskellish_suffixes, cish_suffixes,
    haskellish_user_src_suffixes, haskellish_sig_suffixes
 :: [String]
-- When a file with an extension in the haskellish_src_suffixes group is
-- loaded in --make mode, its imports will be loaded too.
haskellish_src_suffixes :: [String]
haskellish_src_suffixes      = [String]
haskellish_user_src_suffixes [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
                               [ String
"hspp", String
"hscpp" ]
haskellish_suffixes :: [String]
haskellish_suffixes          = [String]
haskellish_src_suffixes [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
                               [ String
"hc", String
"cmm", String
"cmmcpp" ]
cish_suffixes :: [String]
cish_suffixes                = [ String
"c", String
"cpp", String
"C", String
"cc", String
"cxx", String
"s", String
"S", String
"ll", String
"bc", String
"lm_s", String
"m", String
"M", String
"mm" ]

-- Will not be deleted as temp files:
haskellish_user_src_suffixes :: [String]
haskellish_user_src_suffixes =
  [String]
haskellish_sig_suffixes [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [ String
"hs", String
"lhs", String
"hs-boot", String
"lhs-boot" ]
haskellish_sig_suffixes :: [String]
haskellish_sig_suffixes      = [ String
"hsig", String
"lhsig" ]
backpackish_suffixes :: [String]
backpackish_suffixes         = [ String
"bkp" ]

objish_suffixes :: Platform -> [String]
-- Use the appropriate suffix for the system on which
-- the GHC-compiled code will run
objish_suffixes :: Platform -> [String]
objish_suffixes Platform
platform = case Platform -> OS
platformOS Platform
platform of
  OS
OSMinGW32 -> [ String
"o", String
"O", String
"obj", String
"OBJ" ]
  OS
_         -> [ String
"o" ]

dynlib_suffixes :: Platform -> [String]
dynlib_suffixes :: Platform -> [String]
dynlib_suffixes Platform
platform = case Platform -> OS
platformOS Platform
platform of
  OS
OSMinGW32 -> [String
"dll", String
"DLL"]
  OS
OSDarwin  -> [String
"dylib", String
"so"]
  OS
_         -> [String
"so"]

isHaskellishSuffix, isBackpackishSuffix, isHaskellSrcSuffix, isCishSuffix,
    isHaskellUserSrcSuffix, isHaskellSigSuffix
 :: String -> Bool
isHaskellishSuffix :: String -> Bool
isHaskellishSuffix     String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
haskellish_suffixes
isBackpackishSuffix :: String -> Bool
isBackpackishSuffix    String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
backpackish_suffixes
isHaskellSigSuffix :: String -> Bool
isHaskellSigSuffix     String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
haskellish_sig_suffixes
isHaskellSrcSuffix :: String -> Bool
isHaskellSrcSuffix     String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
haskellish_src_suffixes
isCishSuffix :: String -> Bool
isCishSuffix           String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
cish_suffixes
isHaskellUserSrcSuffix :: String -> Bool
isHaskellUserSrcSuffix String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
haskellish_user_src_suffixes

isObjectSuffix, isDynLibSuffix :: Platform -> String -> Bool
isObjectSuffix :: Platform -> String -> Bool
isObjectSuffix Platform
platform String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Platform -> [String]
objish_suffixes Platform
platform
isDynLibSuffix :: Platform -> String -> Bool
isDynLibSuffix Platform
platform String
s = String
s String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Platform -> [String]
dynlib_suffixes Platform
platform

isSourceSuffix :: String -> Bool
isSourceSuffix :: String -> Bool
isSourceSuffix String
suff  = String -> Bool
isHaskellishSuffix String
suff
                    Bool -> Bool -> Bool
|| String -> Bool
isCishSuffix String
suff
                    Bool -> Bool -> Bool
|| String -> Bool
isBackpackishSuffix String
suff

-- | When we are given files (modified by -x arguments) we need
-- to determine if they are Haskellish or not to figure out
-- how we should try to compile it.  The rules are:
--
--      1. If no -x flag was specified, we check to see if
--         the file looks like a module name, has no extension,
--         or has a Haskell source extension.
--
--      2. If an -x flag was specified, we just make sure the
--         specified suffix is a Haskell one.
isHaskellishTarget :: (String, Maybe Phase) -> Bool
isHaskellishTarget :: (String, Maybe Phase) -> Bool
isHaskellishTarget (String
f,Maybe Phase
Nothing) =
  String -> Bool
looksLikeModuleName String
f Bool -> Bool -> Bool
|| String -> Bool
isHaskellSrcFilename String
f Bool -> Bool -> Bool
|| Bool -> Bool
not (String -> Bool
hasExtension String
f)
isHaskellishTarget (String
_,Just Phase
phase) =
  Phase
phase Phase -> [Phase] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [ Bool -> Phase
As Bool
True, Bool -> Phase
As Bool
False, Phase
Cc, Phase
Cobjc, Phase
Cobjcxx, Phase
CmmCpp, Phase
Cmm
                  , Phase
StopLn]

isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
    isHaskellUserSrcFilename, isSourceFilename, isHaskellSigFilename
 :: FilePath -> Bool
-- takeExtension return .foo, so we drop 1 to get rid of the .
isHaskellishFilename :: String -> Bool
isHaskellishFilename     String
f = String -> Bool
isHaskellishSuffix     (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)
isHaskellSrcFilename :: String -> Bool
isHaskellSrcFilename     String
f = String -> Bool
isHaskellSrcSuffix     (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)
isCishFilename :: String -> Bool
isCishFilename           String
f = String -> Bool
isCishSuffix           (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)
isHaskellUserSrcFilename :: String -> Bool
isHaskellUserSrcFilename String
f = String -> Bool
isHaskellUserSrcSuffix (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)
isSourceFilename :: String -> Bool
isSourceFilename         String
f = String -> Bool
isSourceSuffix         (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)
isHaskellSigFilename :: String -> Bool
isHaskellSigFilename     String
f = String -> Bool
isHaskellSigSuffix     (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)

isObjectFilename, isDynLibFilename :: Platform -> FilePath -> Bool
isObjectFilename :: Platform -> String -> Bool
isObjectFilename Platform
platform String
f = Platform -> String -> Bool
isObjectSuffix Platform
platform (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)
isDynLibFilename :: Platform -> String -> Bool
isDynLibFilename Platform
platform String
f = Platform -> String -> Bool
isDynLibSuffix Platform
platform (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ ShowS
takeExtension String
f)