{-# 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 showList :: [Mixin] -> ShowS $cshowList :: [Mixin] -> ShowS show :: Mixin -> String $cshow :: Mixin -> String showsPrec :: Int -> Mixin -> ShowS $cshowsPrec :: Int -> 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 readListPrec :: ReadPrec [Mixin] $creadListPrec :: ReadPrec [Mixin] readPrec :: ReadPrec Mixin $creadPrec :: ReadPrec Mixin readList :: ReadS [Mixin] $creadList :: ReadS [Mixin] readsPrec :: Int -> ReadS Mixin $creadsPrec :: Int -> ReadS Mixin Read, Mixin -> Mixin -> Bool (Mixin -> Mixin -> Bool) -> (Mixin -> Mixin -> Bool) -> Eq Mixin forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Mixin -> Mixin -> Bool $c/= :: Mixin -> Mixin -> Bool == :: Mixin -> Mixin -> Bool $c== :: 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 min :: Mixin -> Mixin -> Mixin $cmin :: Mixin -> Mixin -> Mixin max :: Mixin -> Mixin -> Mixin $cmax :: Mixin -> Mixin -> Mixin >= :: Mixin -> Mixin -> Bool $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 compare :: Mixin -> Mixin -> Ordering $ccompare :: Mixin -> Mixin -> Ordering 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 -> DataType Mixin -> Constr (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) gmapMo :: 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 gmapMp :: forall (m :: * -> *). MonadPlus 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 gmapM :: forall (m :: * -> *). Monad m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin $cgmapM :: forall (m :: * -> *). Monad m => (forall d. Data d => d -> m d) -> Mixin -> m Mixin gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Mixin -> u $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Mixin -> u gmapQ :: forall u. (forall d. Data d => d -> u) -> Mixin -> [u] $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Mixin -> [u] gmapQr :: 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 gmapQl :: forall r r'. (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r $cgmapQl :: forall r r'. (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Mixin -> r gmapT :: (forall b. Data b => b -> b) -> Mixin -> Mixin $cgmapT :: (forall b. Data b => b -> b) -> Mixin -> Mixin dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *). Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mixin) $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *). Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Mixin) dataCast1 :: forall (t :: * -> *) (c :: * -> *). Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Mixin) $cdataCast1 :: forall (t :: * -> *) (c :: * -> *). Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Mixin) dataTypeOf :: Mixin -> DataType $cdataTypeOf :: Mixin -> DataType toConstr :: Mixin -> Constr $ctoConstr :: Mixin -> Constr gunfold :: forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Mixin $cgunfold :: forall (c :: * -> *). (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Mixin gfoldl :: forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Mixin -> c Mixin $cgfoldl :: forall (c :: * -> *). (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Mixin -> c 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 $cto :: forall x. Rep Mixin x -> Mixin $cfrom :: forall x. Mixin -> Rep Mixin x 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 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 PWarnType -> String -> m () forall (m :: * -> *). CabalParsing m => PWarnType -> String -> m () parsecWarning PWarnType PWTExperimental String "colon specifier is experimental feature (issue #5660)" 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 parsec m () forall (m :: * -> *). CharParsing m => m () P.spaces IncludeRenaming incl <- m IncludeRenaming forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a parsec Mixin -> m Mixin 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 (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