1{-# LANGUAGE DeriveDataTypeable #-} 2{-# LANGUAGE DeriveGeneric #-} 3-- | See <https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst> 4module Distribution.Backpack.ModuleShape ( 5 -- * Module shapes 6 ModuleShape(..), 7 emptyModuleShape, 8 shapeInstalledPackage, 9) where 10 11import Prelude () 12import Distribution.Compat.Prelude hiding (mod) 13 14import Distribution.ModuleName 15import Distribution.InstalledPackageInfo as IPI 16 17import Distribution.Backpack.ModSubst 18import Distribution.Backpack 19 20import qualified Data.Map as Map 21import qualified Data.Set as Set 22 23----------------------------------------------------------------------- 24-- Module shapes 25 26-- | A 'ModuleShape' describes the provisions and requirements of 27-- a library. We can extract a 'ModuleShape' from an 28-- 'InstalledPackageInfo'. 29data ModuleShape = ModuleShape { 30 modShapeProvides :: OpenModuleSubst, 31 modShapeRequires :: Set ModuleName 32 } 33 deriving (Eq, Show, Generic, Typeable) 34 35instance Binary ModuleShape 36instance Structured ModuleShape 37 38instance ModSubst ModuleShape where 39 modSubst subst (ModuleShape provs reqs) 40 = ModuleShape (modSubst subst provs) (modSubst subst reqs) 41 42-- | The default module shape, with no provisions and no requirements. 43emptyModuleShape :: ModuleShape 44emptyModuleShape = ModuleShape Map.empty Set.empty 45 46-- Food for thought: suppose we apply the Merkel tree optimization. 47-- Imagine this situation: 48-- 49-- component p 50-- signature H 51-- module P 52-- component h 53-- module H 54-- component a 55-- signature P 56-- module A 57-- component q(P) 58-- include p 59-- include h 60-- component r 61-- include q (P) 62-- include p (P) requires (H) 63-- include h (H) 64-- include a (A) requires (P) 65-- 66-- Component r should not have any conflicts, since after mix-in linking 67-- the two P imports will end up being the same, so we can properly 68-- instantiate it. But to know that q's P is p:P instantiated with h:H, 69-- we have to be able to expand its unit id. Maybe we can expand it 70-- lazily but in some cases it will need to be expanded. 71-- 72-- FWIW, the way that GHC handles this is by improving unit IDs as 73-- soon as it sees an improved one in the package database. This 74-- is a bit disgusting. 75shapeInstalledPackage :: IPI.InstalledPackageInfo -> ModuleShape 76shapeInstalledPackage ipi = ModuleShape (Map.fromList provs) reqs 77 where 78 uid = installedOpenUnitId ipi 79 provs = map shapeExposedModule (IPI.exposedModules ipi) 80 reqs = requiredSignatures ipi 81 shapeExposedModule (IPI.ExposedModule mod_name Nothing) 82 = (mod_name, OpenModule uid mod_name) 83 shapeExposedModule (IPI.ExposedModule mod_name (Just mod)) 84 = (mod_name, mod) 85