{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} module Distribution.Types.Mixin ( Mixin (..) , mkMixin , normaliseMixin ) where import Distribution.Compat.Prelude import Prelude () import Distribution.CabalSpecVersion import Distribution.Parsec import Distribution.Pretty import Distribution.Types.IncludeRenaming import Distribution.Types.LibraryName import Distribution.Types.PackageName import Distribution.Types.UnqualComponentName import qualified Distribution.Compat.CharParsing as P import qualified Text.PrettyPrint as PP -- | -- -- /Invariant:/ if 'mixinLibraryName' is 'LSubLibName', it's not -- the same as 'mixinPackageName'. In other words, -- the same invariant as 'Dependency' has. data Mixin = Mixin { Mixin -> PackageName mixinPackageName :: PackageName , Mixin -> LibraryName mixinLibraryName :: LibraryName , Mixin -> IncludeRenaming mixinIncludeRenaming :: IncludeRenaming } deriving (Int -> Mixin -> ShowS [Mixin] -> ShowS Mixin -> String (Int -> Mixin -> ShowS) -> (Mixin -> String) -> ([Mixin] -> ShowS) -> Show Mixin forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Mixin -> ShowS showsPrec :: Int -> Mixin -> ShowS $cshow :: Mixin -> String show :: Mixin -> String $cshowList :: [Mixin] -> ShowS showList :: [Mixin] -> ShowS Show, ReadPrec [Mixin] ReadPrec Mixin Int -> ReadS Mixin ReadS [Mixin] (Int -> ReadS Mixin) -> ReadS [Mixin] -> ReadPrec Mixin -> ReadPrec [Mixin] -> Read Mixin forall a. (Int -> ReadS a) -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a $creadsPrec :: Int -> ReadS Mixin readsPrec :: Int -> ReadS Mixin $creadList :: ReadS [Mixin] readList :: ReadS [Mixin] $creadPrec :: ReadPrec Mixin readPrec :: ReadPrec Mixin $creadListPrec :: ReadPrec [Mixin] readListPrec :: ReadPrec [Mixin] Read, Mixin -> Mixin -> Bool (Mixin -> Mixin -> Bool) -> (Mixin -> Mixin -> Bool) -> Eq Mixin forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: Mixin -> Mixin -> Bool == :: Mixin -> Mixin -> Bool $c/= :: Mixin -> Mixin -> Bool /= :: Mixin -> Mixin -> Bool Eq, Eq Mixin Eq Mixin => (Mixin -> Mixin -> Ordering) -> (Mixin -> Mixin -> Bool) -> (Mixin -> Mixin -> Bool) -> (Mixin -> Mixin -> Bool) -> (Mixin -> Mixin -> Bool) -> (Mixin -> Mixin -> Mixin) -> (Mixin -> Mixin -> Mixin) -> Ord Mixin Mixin -> Mixin -> Bool Mixin -> Mixin -> Ordering Mixin -> Mixin -> Mixin 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 $ccompare :: Mixin -> Mixin -> Ordering compare :: Mixin -> Mixin -> Ordering $c< :: Mixin -> Mixin -> Bool < :: Mixin -> Mixin -> Bool $c<= :: Mixin -> Mixin -> Bool <= :: Mixin -> Mixin -> Bool $c> :: Mixin -> Mixin -> Bool > :: Mixin -> Mixin -> Bool $c>= :: Mixin -> Mixin -> Bool >= :: Mixin -> Mixin -> Bool $cmax :: Mixin -> Mixin -> Mixin max :: Mixin -> Mixin -> Mixin $cmin :: Mixin -> Mixin -> Mixin min :: Mixin -> Mixin -> Mixin Ord, Typeable, Typeable Mixin Typeable Mixin => (forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Mixin -> c Mixin) -> (forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Mixin) -> (Mixin -> Constr) -> (Mixin -> DataType) -> (forall (t :: * -> *) (c :: * -> *). Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Mixin)) -> (forall (t :: * -> * -> *) (c :: * -> *). Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mixin)) -> ((forall b. Data b => b -> b) -> Mixin -> Mixin) -> (forall r r'. (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r) -> (forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r) -> (forall u. (forall d. Data d => d -> u) -> Mixin -> [u]) -> (forall u. Int -> (forall d. Data d => d -> u) -> Mixin -> u) -> (forall (m :: * -> *). Monad m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin) -> (forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin) -> (forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin) -> Data Mixin Mixin -> Constr Mixin -> DataType (forall b. Data b => b -> b) -> Mixin -> Mixin forall a. Typeable a => (forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> a -> c a) -> (forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c a) -> (a -> Constr) -> (a -> DataType) -> (forall (t :: * -> *) (c :: * -> *). Typeable t => (forall d. Data d => c (t d)) -> Maybe (c a)) -> (forall (t :: * -> * -> *) (c :: * -> *). Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a)) -> ((forall b. Data b => b -> b) -> a -> a) -> (forall r r'. (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r) -> (forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r) -> (forall u. (forall d. Data d => d -> u) -> a -> [u]) -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u) -> (forall (m :: * -> *). Monad m => (forall d. Data d => d -> m d) -> a -> m a) -> (forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> a -> m a) -> (forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> a -> m a) -> Data a forall u. Int -> (forall d. Data d => d -> u) -> Mixin -> u forall u. (forall d. Data d => d -> u) -> Mixin -> [u] forall r r'. (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r forall (m :: * -> *). Monad m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Mixin forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Mixin -> c Mixin forall (t :: * -> *) (c :: * -> *). Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Mixin) forall (t :: * -> * -> *) (c :: * -> *). Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mixin) $cgfoldl :: forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Mixin -> c Mixin gfoldl :: forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Mixin -> c Mixin $cgunfold :: forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Mixin gunfold :: forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Mixin $ctoConstr :: Mixin -> Constr toConstr :: Mixin -> Constr $cdataTypeOf :: Mixin -> DataType dataTypeOf :: Mixin -> DataType $cdataCast1 :: forall (t :: * -> *) (c :: * -> *). Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Mixin) dataCast1 :: forall (t :: * -> *) (c :: * -> *). Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Mixin) $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *). Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mixin) dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *). Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mixin) $cgmapT :: (forall b. Data b => b -> b) -> Mixin -> Mixin gmapT :: (forall b. Data b => b -> b) -> Mixin -> Mixin $cgmapQl :: forall r r'. (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r gmapQl :: forall r r'. (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r $cgmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Mixin -> [u] gmapQ :: forall u. (forall d. Data d => d -> u) -> Mixin -> [u] $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Mixin -> u gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Mixin -> u $cgmapM :: forall (m :: * -> *). Monad m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin gmapM :: forall (m :: * -> *). Monad m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin $cgmapMp :: forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin gmapMp :: forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin $cgmapMo :: forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin gmapMo :: forall (m :: * -> *). MonadPlus m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin Data, (forall x. Mixin -> Rep Mixin x) -> (forall x. Rep Mixin x -> Mixin) -> Generic Mixin forall x. Rep Mixin x -> Mixin forall x. Mixin -> Rep Mixin x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cfrom :: forall x. Mixin -> Rep Mixin x from :: forall x. Mixin -> Rep Mixin x $cto :: forall x. Rep Mixin x -> Mixin to :: forall x. Rep Mixin x -> Mixin Generic) instance Binary Mixin instance Structured Mixin instance NFData Mixin where rnf :: Mixin -> () rnf = Mixin -> () forall a. (Generic a, GNFData (Rep a)) => a -> () genericRnf instance Pretty Mixin where pretty :: Mixin -> Doc pretty (Mixin PackageName pn LibraryName LMainLibName IncludeRenaming incl) = PackageName -> Doc forall a. Pretty a => a -> Doc pretty PackageName pn Doc -> Doc -> Doc <+> IncludeRenaming -> Doc forall a. Pretty a => a -> Doc pretty IncludeRenaming incl pretty (Mixin PackageName pn (LSubLibName UnqualComponentName ln) IncludeRenaming incl) = PackageName -> Doc forall a. Pretty a => a -> Doc pretty PackageName pn Doc -> Doc -> Doc <<>> Doc PP.colon Doc -> Doc -> Doc <<>> UnqualComponentName -> Doc forall a. Pretty a => a -> Doc pretty UnqualComponentName ln Doc -> Doc -> Doc <+> IncludeRenaming -> Doc forall a. Pretty a => a -> Doc pretty IncludeRenaming incl -- | -- -- >>> simpleParsec "mylib" :: Maybe Mixin -- Just (Mixin {mixinPackageName = PackageName "mylib", mixinLibraryName = LMainLibName, mixinIncludeRenaming = IncludeRenaming {includeProvidesRn = DefaultRenaming, includeRequiresRn = DefaultRenaming}}) -- -- >>> simpleParsec "thatlib:sublib" :: Maybe Mixin -- Just (Mixin {mixinPackageName = PackageName "thatlib", mixinLibraryName = LSubLibName (UnqualComponentName "sublib"), mixinIncludeRenaming = IncludeRenaming {includeProvidesRn = DefaultRenaming, includeRequiresRn = DefaultRenaming}}) -- -- >>> simpleParsec "thatlib:thatlib" :: Maybe Mixin -- Just (Mixin {mixinPackageName = PackageName "thatlib", mixinLibraryName = LMainLibName, mixinIncludeRenaming = IncludeRenaming {includeProvidesRn = DefaultRenaming, includeRequiresRn = DefaultRenaming}}) -- -- Sublibrary syntax is accepted since @cabal-version: 3.4@. -- -- >>> map (`simpleParsec'` "mylib:sub") [CabalSpecV3_0, CabalSpecV3_4] :: [Maybe Mixin] -- [Nothing,Just (Mixin {mixinPackageName = PackageName "mylib", mixinLibraryName = LSubLibName (UnqualComponentName "sub"), mixinIncludeRenaming = IncludeRenaming {includeProvidesRn = DefaultRenaming, includeRequiresRn = DefaultRenaming}})] instance Parsec Mixin where parsec :: forall (m :: * -> *). CabalParsing m => m Mixin parsec = do pn <- m PackageName forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a forall (m :: * -> *). CabalParsing m => m PackageName parsec ln <- P.option LMainLibName $ do _ <- P.char ':' versionGuardMultilibs LSubLibName <$> parsec P.spaces incl <- parsec return (mkMixin pn ln incl) versionGuardMultilibs :: CabalParsing m => m () versionGuardMultilibs :: forall (m :: * -> *). CabalParsing m => m () versionGuardMultilibs = do csv <- m CabalSpecVersion forall (m :: * -> *). CabalParsing m => m CabalSpecVersion askCabalSpecVersion when (csv < CabalSpecV3_4) $ fail $ unwords [ "Sublibrary mixin syntax used." , "To use this syntax the package needs to specify at least 'cabal-version: 3.4'." ] -- | Smart constructor of 'Mixin', enforces invariant. -- -- @since 3.4.0.0 mkMixin :: PackageName -> LibraryName -> IncludeRenaming -> Mixin mkMixin :: PackageName -> LibraryName -> IncludeRenaming -> Mixin mkMixin PackageName pn (LSubLibName UnqualComponentName uqn) IncludeRenaming incl | PackageName -> UnqualComponentName packageNameToUnqualComponentName PackageName pn UnqualComponentName -> UnqualComponentName -> Bool forall a. Eq a => a -> a -> Bool == UnqualComponentName uqn = PackageName -> LibraryName -> IncludeRenaming -> Mixin Mixin PackageName pn LibraryName LMainLibName IncludeRenaming incl mkMixin PackageName pn LibraryName ln IncludeRenaming incl = PackageName -> LibraryName -> IncludeRenaming -> Mixin Mixin PackageName pn LibraryName ln IncludeRenaming incl -- | Restore invariant normaliseMixin :: Mixin -> Mixin normaliseMixin :: Mixin -> Mixin normaliseMixin (Mixin PackageName pn LibraryName ln IncludeRenaming incl) = PackageName -> LibraryName -> IncludeRenaming -> Mixin mkMixin PackageName pn LibraryName ln IncludeRenaming incl