module UHC.Light.Compiler.EHC.CompileUnit
( EHCompileUnit (..)
, ecuFilePath
, emptyECU
, ecuFinalDestinationState
, EcuUpdater, ecuStoreSrcFilePath, ecuStoreState, ecuStoreHS, ecuStoreEH, ecuStoreHSSem, ecuStoreEHSem
, ecuStoreCoreSemMod
, ecuStoreCoreSem
, ecuStoreCore
, Optim (..), defaultOptim
, ecuHSDeclImpNmS, ecuHIDeclImpNmS, ecuHIUsedImpNmS
, ecuIsMainMod
, ecuImpNmS, ecuImpNmL
, ecuTransClosedUsedModMp, ecuTransClosedOrphanModS
, ecuIsOrphan
, ecuStoreHSDeclImpS, ecuSetNeedsCompile, ecuStoreHIUsedImpS, ecuStoreHIInfoTime, ecuStoreSrcTime, ecuStoreHSSemMod, ecuStoreIntrodModS, ecuStoreHIDeclImpS, ecuStoreMod, ecuSetIsTopMod, ecuSetHasMain, ecuStoreOptim, ecuStoreHIInfo, ecuStorePrevHIInfo
, ecuStoreCoreTime
, ecuStoreDirIsWritable
, ecuIsHSNewerThanHI
, ecuIsValidHIInfo
, ecuCanUseHIInsteadOfHS
, EHCCompileSeqNr (..)
, ecuAnHIInfo
, ecuStoreOpts, ecuStorePragmas, ecuStoreUsedNames, ecuSetTarget
, ecuStoreGenCodeFiles
, ecuStoreCppFilePath, ecuStoreSeqNr )
where
import qualified Data.Map as Map
import qualified Data.Set as Set
import UHC.Light.Compiler.EHC.Common
import qualified UHC.Light.Compiler.HS as HS
import qualified UHC.Light.Compiler.EH as EH
import qualified UHC.Light.Compiler.Core as Core
import qualified UHC.Light.Compiler.EH.MainAG as EHSem
import qualified UHC.Light.Compiler.HS.MainAG as HSSem
import qualified UHC.Light.Compiler.Core.ToGrin as Core2GrSem
import qualified UHC.Light.Compiler.Core.Check as Core2ChkSem
import qualified UHC.Light.Compiler.HI as HI
import qualified UHC.Light.Compiler.HS.ModImpExp as HSSemMod
import UHC.Light.Compiler.Module.ImportExport
import UHC.Light.Compiler.CodeGen.ImportUsedModules
import UHC.Util.Time
import System.Directory
import qualified UHC.Light.Compiler.Base.Pragma as Pragma
import UHC.Light.Compiler.Base.Target
import UHC.Util.Debug
data Optim
= Optim
defaultOptim :: Optim
defaultOptim
= Optim
data EHCCompileSeqNr
= EHCCompileSeqNr
{ ecseqnrThis :: !Int
, ecseqnrTotal :: !Int
}
deriving (Eq,Ord)
zeroEHCCompileSeqNr :: EHCCompileSeqNr
zeroEHCCompileSeqNr = EHCCompileSeqNr 0 0
instance Show EHCCompileSeqNr where
show (EHCCompileSeqNr this total)
= "[" ++ replicate (length tot length ths) ' ' ++ ths ++ "/" ++ tot ++ "]"
where tot = show total
ths = show this
data EHCompileUnit
= EHCompileUnit
{ ecuSrcFilePath :: !FPath
, ecuMbCppFilePath :: !(Maybe FPath)
, ecuFileLocation :: !FileLoc
, ecuGrpNm :: !HsName
, ecuModNm :: !HsName
, ecuMbHS :: !(Maybe HS.AGItf)
, ecuMbHSSem :: !(Maybe HSSem.Syn_AGItf)
, ecuMbEH :: !(Maybe EH.AGItf)
, ecuMbEHSem :: !(Maybe EHSem.Syn_AGItf)
, ecuMbCore :: !(Maybe Core.CModule)
, ecuMbCoreSem :: !(Maybe Core2GrSem.Syn_CodeAGItf)
, ecuMbCoreSemMod :: !(Maybe Core2ChkSem.Syn_CodeAGItf)
, ecuState :: !EHCompileUnitState
, ecuImportUsedModules :: !ImportUsedModules
, ecuIsTopMod :: !Bool
, ecuHasMain :: !Bool
, ecuNeedsCompile :: !Bool
, ecuMbSrcTime :: !(Maybe ClockTime)
, ecuMbHIInfoTime :: !(Maybe ClockTime)
, ecuMbCoreTime :: !(Maybe ClockTime)
, ecuMbHSSemMod :: !(Maybe HSSemMod.Syn_AGItf)
, ecuMod :: !Mod
, ecuMbPrevHIInfo :: !(Maybe HI.HIInfo)
, ecuMbOptim :: !(Maybe Optim)
, ecuHIInfo :: !HI.HIInfo
, ecuDirIsWritable :: !Bool
, ecuMbOpts :: (Maybe EHCOpts)
, ecuTarget :: Target
, ecuPragmas :: !(Set.Set Pragma.Pragma)
, ecuUsedNames :: ModEntRelFilterMp
, ecuSeqNr :: !EHCCompileSeqNr
, ecuGenCodeFiles :: ![FPath]
}
ecuHSDeclImpNmS = iumHSDeclModules . ecuImportUsedModules
ecuHIDeclImpNmS = iumHIDeclModules . ecuImportUsedModules
ecuHIUsedImpNmS = iumHIUsedModules . ecuImportUsedModules
ecuFilePath :: EHCompileUnit -> FPath
ecuFilePath ecu
= maybe (ecuSrcFilePath ecu) id (ecuMbCppFilePath ecu)
ecuIsMainMod :: EHCompileUnit -> Bool
ecuIsMainMod e = ecuIsTopMod e && ecuHasMain e
ecuAnHIInfo :: EHCompileUnit -> HI.HIInfo
ecuAnHIInfo e
= case ecuMbPrevHIInfo e of
Just pi | HI.hiiIsEmpty hii
-> pi
_ -> hii
where hii = ecuHIInfo e
emptyECU :: EHCompileUnit
emptyECU
= EHCompileUnit
{ ecuSrcFilePath = emptyFPath
, ecuMbCppFilePath = Nothing
, ecuFileLocation = emptyFileLoc
, ecuGrpNm = hsnUnknown
, ecuModNm = hsnUnknown
, ecuMbHS = Nothing
, ecuMbHSSem = Nothing
, ecuMbEH = Nothing
, ecuMbEHSem = Nothing
, ecuMbCore = Nothing
, ecuMbCoreSem = Nothing
, ecuMbCoreSemMod = Nothing
, ecuState = ECUS_Unknown
, ecuImportUsedModules = emptyImportUsedModules
, ecuIsTopMod = False
, ecuHasMain = False
, ecuNeedsCompile = True
, ecuMbSrcTime = Nothing
, ecuMbHIInfoTime = Nothing
, ecuMbCoreTime = Nothing
, ecuMbHSSemMod = Nothing
, ecuMod = emptyMod
, ecuMbPrevHIInfo = Nothing
, ecuMbOptim = Nothing
, ecuHIInfo = HI.emptyHIInfo
, ecuDirIsWritable = False
, ecuMbOpts = Nothing
, ecuTarget = defaultTarget
, ecuPragmas = Set.empty
, ecuUsedNames = Map.empty
, ecuSeqNr = zeroEHCCompileSeqNr
, ecuGenCodeFiles = []
}
ecuImpNmS :: EHCompileUnit -> Set.Set HsName
ecuImpNmS ecu =
Set.delete (ecuModNm ecu) $ Set.unions [ ecuHSDeclImpNmS ecu, ecuHIDeclImpNmS ecu, ecuHIUsedImpNmS ecu ]
ecuImpNmL :: EHCompileUnit -> [HsName]
ecuImpNmL = Set.toList . ecuImpNmS
ecuTransClosedUsedModMp :: EHCompileUnit -> HI.HIInfoUsedModMp
ecuTransClosedUsedModMp = HI.hiiTransClosedUsedModMp . ecuAnHIInfo
ecuTransClosedOrphanModS :: EHCompileUnit -> Set.Set HsName
ecuTransClosedOrphanModS = HI.hiiTransClosedOrphanModS . ecuAnHIInfo
ecuIsOrphan :: EHCompileUnit -> Bool
ecuIsOrphan = isJust . HI.hiiMbOrphan . ecuAnHIInfo
instance CompileUnitState EHCompileUnitState where
cusDefault = ECUS_Eh EHStart
cusUnk = ECUS_Unknown
cusIsUnk = (==ECUS_Unknown)
cusIsImpKnown s = case s of
ECUS_Haskell HSOnlyImports -> True
ECUS_Haskell HIOnlyImports -> True
ECUS_Haskell HMOnlyMinimal -> True
ECUS_Haskell LHSOnlyImports -> True
ECUS_Haskell HSAllSem -> True
ECUS_Haskell HIAllSem -> True
ECUS_Core CROnlyImports -> True
_ -> False
instance FileLocatable EHCompileUnit FileLoc where
fileLocation = ecuFileLocation
noFileLocation = emptyFileLoc
instance CompileUnit EHCompileUnit HsName FileLoc EHCompileUnitState where
cuDefault = emptyECU
cuFPath = ecuFilePath
cuLocation = fileLocation
cuKey = ecuModNm
cuState = ecuState
cuUpdFPath = ecuStoreSrcFilePath
cuUpdLocation = ecuStoreFileLocation
cuUpdState = ecuStoreState
cuUpdKey nm u = u {ecuModNm = nm}
cuImports = ecuImpNmL
cuParticipation u = if not (Set.null $ Set.filter (Pragma.pragmaIsExcludeTarget $ ecuTarget u) $ ecuPragmas u)
then [CompileParticipation_NoImport]
else []
instance FPathError Err
instance CompileRunError Err () where
crePPErrL = ppErrL
creMkNotFoundErrL _ fp sp sufs = [rngLift emptyRange Err_FileNotFound fp sp sufs]
creAreFatal = errLIsFatal
instance CompileModName HsName where
mkCMNm = hsnFromString
instance Show EHCompileUnit where
show _ = "EHCompileUnit"
instance PP EHCompileUnit where
pp ecu
= ecuModNm ecu >|<
":" >#< ppBracketsCommas (ecuImpNmL ecu) >|<
"," >#< show (ecuState ecu)
ecuFinalDestinationState :: EHCompileUnit -> EHCompileUnitState
ecuFinalDestinationState ecu = ecuStateFinalDestination upd $ ecuState ecu
where
upd (ECUS_Haskell _)
| ecuNeedsCompile ecu = ECUS_Haskell HSAllSem
| otherwise = ECUS_Haskell HIAllSem
upd s = s
type EcuUpdater a = a -> EHCompileUnit -> EHCompileUnit
ecuStoreSrcFilePath :: EcuUpdater FPath
ecuStoreSrcFilePath x ecu = ecu { ecuSrcFilePath = x }
ecuStoreFileLocation :: EcuUpdater FileLoc
ecuStoreFileLocation x ecu = ecu { ecuFileLocation = x }
ecuStoreState :: EcuUpdater EHCompileUnitState
ecuStoreState x ecu = ecu { ecuState = x }
ecuStoreHS :: EcuUpdater HS.AGItf
ecuStoreHS x ecu = ecu { ecuMbHS = Just x }
ecuStoreEH :: EcuUpdater EH.AGItf
ecuStoreEH x ecu = ecu { ecuMbEH = Just x }
ecuStoreHSSem :: EcuUpdater HSSem.Syn_AGItf
ecuStoreHSSem x ecu = ecu { ecuMbHSSem = Just x }
ecuStoreEHSem :: EcuUpdater EHSem.Syn_AGItf
ecuStoreEHSem x ecu = ecu { ecuMbEHSem = Just x }
ecuStoreCoreSemMod :: EcuUpdater Core2ChkSem.Syn_CodeAGItf
ecuStoreCoreSemMod x ecu = ecu { ecuMbCoreSemMod = Just x }
ecuStoreCoreSem :: EcuUpdater Core2GrSem.Syn_CodeAGItf
ecuStoreCoreSem x ecu = ecu { ecuMbCoreSem = Just x }
ecuStoreCore :: EcuUpdater Core.CModule
ecuStoreCore x ecu | x `seq` True = ecu { ecuMbCore = Just x }
ecuStoreSrcTime :: EcuUpdater ClockTime
ecuStoreSrcTime x ecu = ecu { ecuMbSrcTime = Just x }
ecuStoreHIInfoTime :: EcuUpdater ClockTime
ecuStoreHIInfoTime x ecu = ecu { ecuMbHIInfoTime = Just x }
ecuStoreHSSemMod :: EcuUpdater HSSemMod.Syn_AGItf
ecuStoreHSSemMod x ecu = ecu { ecuMbHSSemMod = Just x }
ecuStoreHSDeclImpS :: EcuUpdater (Set.Set HsName)
ecuStoreHSDeclImpS x ecu = ecu { ecuImportUsedModules = ium {iumHSDeclModules = x} }
where ium = ecuImportUsedModules ecu
ecuStoreHIDeclImpS :: EcuUpdater (Set.Set HsName)
ecuStoreHIDeclImpS x ecu = ecu { ecuImportUsedModules = ium {iumHIDeclModules = x} }
where ium = ecuImportUsedModules ecu
ecuStoreHIUsedImpS :: EcuUpdater (Set.Set HsName)
ecuStoreHIUsedImpS x ecu = ecu { ecuImportUsedModules = ium {iumHIUsedModules = x} }
where ium = ecuImportUsedModules ecu
ecuStoreIntrodModS :: EcuUpdater (Set.Set HsName)
ecuStoreIntrodModS x ecu = ecu { ecuImportUsedModules = ium {iumIntrodModules = x} }
where ium = ecuImportUsedModules ecu
ecuStoreMod :: EcuUpdater Mod
ecuStoreMod x ecu = ecu { ecuMod = x }
ecuSetIsTopMod :: EcuUpdater Bool
ecuSetIsTopMod x ecu = ecu { ecuIsTopMod = x }
ecuSetHasMain :: EcuUpdater Bool
ecuSetHasMain x ecu = ecu { ecuHasMain = x }
ecuSetNeedsCompile :: EcuUpdater Bool
ecuSetNeedsCompile x ecu = ecu { ecuNeedsCompile = x }
ecuStorePrevHIInfo :: EcuUpdater HI.HIInfo
ecuStorePrevHIInfo x ecu = ecu { ecuMbPrevHIInfo = Just x }
ecuStoreOptim :: EcuUpdater Optim
ecuStoreOptim x ecu = ecu { ecuMbOptim = Just x }
ecuStoreHIInfo :: EcuUpdater HI.HIInfo
ecuStoreHIInfo x ecu | x `seq` True = ecu { ecuHIInfo = x }
ecuStoreCoreTime :: EcuUpdater ClockTime
ecuStoreCoreTime x ecu = ecu { ecuMbCoreTime = Just x }
ecuStoreDirIsWritable :: EcuUpdater Bool
ecuStoreDirIsWritable x ecu = ecu { ecuDirIsWritable = x }
ecuStoreOpts :: EcuUpdater EHCOpts
ecuStoreOpts x ecu = ecu { ecuMbOpts = Just x }
ecuSetTarget :: EcuUpdater Target
ecuSetTarget x ecu = ecu { ecuTarget = x }
ecuStorePragmas :: EcuUpdater (Set.Set Pragma.Pragma)
ecuStorePragmas x ecu = ecu { ecuPragmas = x }
ecuStoreUsedNames :: EcuUpdater ModEntRelFilterMp
ecuStoreUsedNames x ecu = ecu { ecuUsedNames = x }
ecuStoreGenCodeFiles :: EcuUpdater [FPath]
ecuStoreGenCodeFiles x ecu = ecu { ecuGenCodeFiles = x }
ecuStoreSeqNr :: EcuUpdater EHCCompileSeqNr
ecuStoreSeqNr x ecu = ecu { ecuSeqNr = x }
ecuStoreCppFilePath :: EcuUpdater FPath
ecuStoreCppFilePath x ecu = ecu { ecuMbCppFilePath = Just x }
ecuIsHSNewerThanHI :: EHCompileUnit -> Bool
ecuIsHSNewerThanHI ecu
= case (ecuMbSrcTime ecu,ecuMbHIInfoTime ecu) of
(Just ths,Just thi) -> ths `diffClockTimes` thi > noTimeDiff
(Nothing ,Just thi) -> False
_ -> True
ecuIsValidHIInfo :: EHCompileUnit -> Bool
ecuIsValidHIInfo ecu
= case ecuMbPrevHIInfo ecu of
Just i -> HI.hiiValidity i == HI.HIValidity_Ok
_ -> False
ecuCanUseHIInsteadOfHS :: EHCompileUnit -> Bool
ecuCanUseHIInsteadOfHS ecu
= ecuIsValidHIInfo ecu && not (ecuIsHSNewerThanHI ecu)