{-# 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 PackageName pn <- m PackageName forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a forall (m :: * -> *). CabalParsing m => m PackageName parsec LibraryName ln <- LibraryName -> m LibraryName -> m LibraryName forall (m :: * -> *) a. Alternative m => a -> m a -> m a P.option LibraryName LMainLibName (m LibraryName -> m LibraryName) -> m LibraryName -> m LibraryName forall a b. (a -> b) -> a -> b $ do Char _ <- Char -> m Char forall (m :: * -> *). CharParsing m => Char -> m Char P.char Char ':' m () forall (m :: * -> *). CabalParsing m => m () versionGuardMultilibs UnqualComponentName -> LibraryName LSubLibName (UnqualComponentName -> LibraryName) -> m UnqualComponentName -> m LibraryName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> m UnqualComponentName forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a forall (m :: * -> *). CabalParsing m => m UnqualComponentName parsec m () forall (m :: * -> *). CharParsing m => m () P.spaces IncludeRenaming incl <- m IncludeRenaming forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a forall (m :: * -> *). CabalParsing m => m IncludeRenaming parsec Mixin -> m Mixin forall a. a -> m a forall (m :: * -> *) a. Monad m => a -> m a return (PackageName -> LibraryName -> IncludeRenaming -> Mixin mkMixin PackageName pn LibraryName ln IncludeRenaming incl) where versionGuardMultilibs :: CabalParsing m => m () versionGuardMultilibs :: forall (m :: * -> *). CabalParsing m => m () versionGuardMultilibs = do CabalSpecVersion csv <- m CabalSpecVersion forall (m :: * -> *). CabalParsing m => m CabalSpecVersion askCabalSpecVersion Bool -> m () -> m () forall (f :: * -> *). Applicative f => Bool -> f () -> f () when (CabalSpecVersion csv CabalSpecVersion -> CabalSpecVersion -> Bool forall a. Ord a => a -> a -> Bool < CabalSpecVersion CabalSpecV3_4) (m () -> m ()) -> m () -> m () forall a b. (a -> b) -> a -> b $ String -> m () forall a. String -> m a forall (m :: * -> *) a. MonadFail m => String -> m a fail (String -> m ()) -> String -> m () forall a b. (a -> b) -> a -> b $ [String] -> String unwords [ String "Sublibrary mixin syntax used." , String "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