module UHC.Light.Compiler.Base.FileSearchLocation ( mkDirFileLoc , StringPath, FileLocPath , FileLocKind (..) , FileLoc (..), emptyFileLoc, fileLocPkgDb , mkPkgFileLoc , filelocIsPkg , FileSearchLoc , PkgKey, PkgKey1, PkgKey2 , showPkgKey , PackageSearchFilter (..) , pkgSearchFilter , PackageCfgKeyVals, PackageInfo (..), PackageMp, Module2PackageMp, PackageDatabase (..), emptyPackageMp, emptyPackageDatabase , mkInternalPkgFileBase ) where import UHC.Light.Compiler.Base.Common import qualified Data.Set as Set import qualified Data.Map as Map import Data.Maybe import Data.Version import Data.List import UHC.Util.Pretty import UU.Parsing import UHC.Util.ParseUtils import UHC.Util.ScanUtils import UHC.Light.Compiler.Base.HsName import UHC.Light.Compiler.Base.Target import qualified UHC.Light.Compiler.ConfigInstall as Cfg import UHC.Util.Hashable {-# LINE 47 "src/ehc/Base/FileSearchLocation.chs" #-} data FileLocKind = FileLocKind_Dir -- plain directory | FileLocKind_Pkg PkgKey -- specific package String -- with the dir inside package it was found | FileLocKind_PkgDb -- yet unknown package in the package database deriving (Eq,Ord,Generic,Typeable) instance Hashable FileLocKind instance Show FileLocKind where show FileLocKind_Dir = "directory" show (FileLocKind_Pkg p d) = "package: " ++ showPkgKey p ++ "(in: " ++ d ++ ")" show FileLocKind_PkgDb = "package database" instance PP FileLocKind where pp = pp . show {-# LINE 80 "src/ehc/Base/FileSearchLocation.chs" #-} data FileLoc = FileLoc { filelocKind :: FileLocKind , filelocDir :: String } deriving (Eq,Ord,Generic,Typeable) instance Hashable FileLoc instance Show FileLoc where show (FileLoc k d) = d ++ " (" ++ show k ++ ")" instance PP FileLoc where pp = pp . show emptyFileLoc :: FileLoc emptyFileLoc = FileLoc FileLocKind_Dir "" fileLocPkgDb :: FileLoc fileLocPkgDb = FileLoc FileLocKind_PkgDb "" {-# LINE 103 "src/ehc/Base/FileSearchLocation.chs" #-} mkDirFileLoc = FileLoc FileLocKind_Dir {-# LINE 112 "src/ehc/Base/FileSearchLocation.chs" #-} mkPkgFileLoc :: PkgKey -> String -> FileLoc mkPkgFileLoc p d = FileLoc (FileLocKind_Pkg p d) d {-# LINE 117 "src/ehc/Base/FileSearchLocation.chs" #-} filelocIsPkg :: FileLoc -> Bool filelocIsPkg (FileLoc (FileLocKind_Pkg _ _) _) = True filelocIsPkg (FileLoc FileLocKind_PkgDb _) = True filelocIsPkg _ = False {-# LINE 124 "src/ehc/Base/FileSearchLocation.chs" #-} type StringPath = [String] type FileLocPath = [FileLoc] {-# LINE 133 "src/ehc/Base/FileSearchLocation.chs" #-} type FileSearchLoc = FileLoc {-# LINE 141 "src/ehc/Base/FileSearchLocation.chs" #-} type PkgKey1 = PkgName type PkgKey2 = Maybe Version type PkgKey = (PkgKey1,PkgKey2) instance HSNM PkgKey where mkHNm (n,Just v) = mkHNmBase (n ++ "-" ++ (concat $ intersperse "." $ map show $ versionBranch v)) mkHNm (n,_ ) = mkHNm n {-# LINE 155 "src/ehc/Base/FileSearchLocation.chs" #-} showPkgKey :: PkgKey -> String showPkgKey = show . mkHNm {-# LINE 164 "src/ehc/Base/FileSearchLocation.chs" #-} -- | Description of hiding/exposing pkgs, determining the used packages for looking up modules. data PackageSearchFilter -- Note: the below order is important, it is used for sorting just before having its effect on searchable packages. -- The current order means that in its filtering hiding is done first, thereby starting out with all available pkgs, then hide (all), then expose selectively = PackageSearchFilter_HideAll | PackageSearchFilter_HidePkg [PkgKey] | PackageSearchFilter_ExposePkg [PkgKey] deriving (Show, Eq, Ord) {-# LINE 175 "src/ehc/Base/FileSearchLocation.chs" #-} pkgSearchFilter :: (x -> Maybe PkgKey) -> ([PkgKey] -> PackageSearchFilter) -> [x] -> [PackageSearchFilter] pkgSearchFilter mkKey mk ss = if null ps then [] else [mk ps] where ps = catMaybes $ map mkKey ss {-# LINE 186 "src/ehc/Base/FileSearchLocation.chs" #-} type PackageCfgKeyVals = Map.Map String String -- | Per package info data PackageInfo = PackageInfo { pkginfoLoc :: !FileLoc -- ^ directory location , pkginfoOrder :: !Int -- ^ for multiple packages the relative order -- , pkginfoKeyVals :: PackageCfgKeyVals -- key/value pairs of pkg config info , pkginfoExposedModules :: !HsNameS -- ^ exposed modules , pkginfoBuildDepends :: !(Set.Set PkgKey) -- ^ pkgs dependend on , pkginfoIsExposed :: !Bool -- ^ pkg is exposed? } deriving Show -- | content of a package (keys are name, then version) type PackageMp = Map.Map PkgKey1 (Map.Map PkgKey2 [PackageInfo]) emptyPackageMp :: PackageMp emptyPackageMp = Map.empty -- | reverse map from module name to package key type Module2PackageMp = Map.Map HsName [PkgKey] -- | A package database contains an actual package map, plus a function -- that maps modules to associated package maps. The latter is computed -- by "freezing" the package database using "pkgDbFreeze". data PackageDatabase = PackageDatabase { pkgDbPkgMp :: PackageMp , pkgDbMod2PkgMp :: Module2PackageMp } deriving Show emptyPackageDatabase :: PackageDatabase emptyPackageDatabase = PackageDatabase emptyPackageMp Map.empty {-# LINE 228 "src/ehc/Base/FileSearchLocation.chs" #-} mkInternalPkgFileBase :: PkgKey -> String {- compiler name/version -} -> Target -> TargetFlavor -> FilePath mkInternalPkgFileBase pkgKey compversion tgt tgtv = Cfg.mkInternalPkgFileBase (showPkgKey pkgKey) compversion (show tgt) (show tgtv)