    module Distribution.Solver.Types.PackagePath
        ( PackagePath(..)
        , Namespace(..)
        , Qualifier(..)
        , dispQualifier
        , Qualified(..)
        , QPN
        , dispQPN
        , showQPN
        ) where

    import Distribution.Solver.Compat.Prelude
    import Prelude ()
    import Distribution.Package (PackageName)
    import Distribution.Pretty (pretty, flatStyle)
    import qualified Text.PrettyPrint as Disp

    -- | A package path consists of a namespace and a package path inside that
    -- namespace.
    data PackagePath = PackagePath Namespace Qualifier
      deriving (PackagePath -> PackagePath -> Bool
    (PackagePath -> PackagePath -> Bool)
    -> (PackagePath -> PackagePath -> Bool) -> Eq PackagePath
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PackagePath -> PackagePath -> Bool
    == :: PackagePath -> PackagePath -> Bool
    $c/= :: PackagePath -> PackagePath -> Bool
    /= :: PackagePath -> PackagePath -> Bool
    Eq, Eq PackagePath
    Eq PackagePath =>
    (PackagePath -> PackagePath -> Ordering)
    -> (PackagePath -> PackagePath -> Bool)
    -> (PackagePath -> PackagePath -> Bool)
    -> (PackagePath -> PackagePath -> Bool)
    -> (PackagePath -> PackagePath -> Bool)
    -> (PackagePath -> PackagePath -> PackagePath)
    -> (PackagePath -> PackagePath -> PackagePath)
    -> Ord PackagePath
    PackagePath -> PackagePath -> Bool
    PackagePath -> PackagePath -> Ordering
    PackagePath -> PackagePath -> PackagePath
    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 :: PackagePath -> PackagePath -> Ordering
    compare :: PackagePath -> PackagePath -> Ordering
    $c< :: PackagePath -> PackagePath -> Bool
    < :: PackagePath -> PackagePath -> Bool
    $c<= :: PackagePath -> PackagePath -> Bool
    <= :: PackagePath -> PackagePath -> Bool
    $c> :: PackagePath -> PackagePath -> Bool
    > :: PackagePath -> PackagePath -> Bool
    $c>= :: PackagePath -> PackagePath -> Bool
    >= :: PackagePath -> PackagePath -> Bool
    $cmax :: PackagePath -> PackagePath -> PackagePath
    max :: PackagePath -> PackagePath -> PackagePath
    $cmin :: PackagePath -> PackagePath -> PackagePath
    min :: PackagePath -> PackagePath -> PackagePath
    Ord, Int -> PackagePath -> ShowS
    [PackagePath] -> ShowS
    PackagePath -> String
    (Int -> PackagePath -> ShowS)
    -> (PackagePath -> String)
    -> ([PackagePath] -> ShowS)
    -> Show PackagePath
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PackagePath -> ShowS
    showsPrec :: Int -> PackagePath -> ShowS
    $cshow :: PackagePath -> String
    show :: PackagePath -> String
    $cshowList :: [PackagePath] -> ShowS
    showList :: [PackagePath] -> ShowS
    Show)

    -- | Top-level namespace
    --
    -- Package choices in different namespaces are considered completely independent
    -- by the solver.
    data Namespace =
        -- | The default namespace
        DefaultNamespace

        -- | A namespace for a specific build target
      | Independent PackageName
      deriving (Namespace -> Namespace -> Bool
    (Namespace -> Namespace -> Bool)
    -> (Namespace -> Namespace -> Bool) -> Eq Namespace
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Namespace -> Namespace -> Bool
    == :: Namespace -> Namespace -> Bool
    $c/= :: Namespace -> Namespace -> Bool
    /= :: Namespace -> Namespace -> Bool
    Eq, Eq Namespace
    Eq Namespace =>
    (Namespace -> Namespace -> Ordering)
    -> (Namespace -> Namespace -> Bool)
    -> (Namespace -> Namespace -> Bool)
    -> (Namespace -> Namespace -> Bool)
    -> (Namespace -> Namespace -> Bool)
    -> (Namespace -> Namespace -> Namespace)
    -> (Namespace -> Namespace -> Namespace)
    -> Ord Namespace
    Namespace -> Namespace -> Bool
    Namespace -> Namespace -> Ordering
    Namespace -> Namespace -> Namespace
    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 :: Namespace -> Namespace -> Ordering
    compare :: Namespace -> Namespace -> Ordering
    $c< :: Namespace -> Namespace -> Bool
    < :: Namespace -> Namespace -> Bool
    $c<= :: Namespace -> Namespace -> Bool
    <= :: Namespace -> Namespace -> Bool
    $c> :: Namespace -> Namespace -> Bool
    > :: Namespace -> Namespace -> Bool
    $c>= :: Namespace -> Namespace -> Bool
    >= :: Namespace -> Namespace -> Bool
    $cmax :: Namespace -> Namespace -> Namespace
    max :: Namespace -> Namespace -> Namespace
    $cmin :: Namespace -> Namespace -> Namespace
    min :: Namespace -> Namespace -> Namespace
    Ord, Int -> Namespace -> ShowS
    [Namespace] -> ShowS
    Namespace -> String
    (Int -> Namespace -> ShowS)
    -> (Namespace -> String)
    -> ([Namespace] -> ShowS)
    -> Show Namespace
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Namespace -> ShowS
    showsPrec :: Int -> Namespace -> ShowS
    $cshow :: Namespace -> String
    show :: Namespace -> String
    $cshowList :: [Namespace] -> ShowS
    showList :: [Namespace] -> ShowS
    Show)

    -- | Pretty-prints a namespace. The result is either empty or
    -- ends in a period, so it can be prepended onto a qualifier.
    dispNamespace :: Namespace -> Disp.Doc
    dispNamespace :: Namespace -> Doc
    dispNamespace Namespace
    DefaultNamespace = Doc
    Disp.empty
    dispNamespace (Independent PackageName
    i) = PackageName -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageName
    i Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    "."

    -- | Qualifier of a package within a namespace (see 'PackagePath')
    data Qualifier =
        -- | Top-level dependency in this namespace
        QualToplevel

        -- | Any dependency on base is considered independent
        --
        -- This makes it possible to have base shims.
      | QualBase PackageName

        -- | Setup dependency
        --
        -- By rights setup dependencies ought to be nestable; after all, the setup
        -- dependencies of a package might themselves have setup dependencies, which
        -- are independent from everything else. However, this very quickly leads to
        -- infinite search trees in the solver. Therefore we limit ourselves to
        -- a single qualifier (within a given namespace).
      | QualSetup PackageName

        -- | If we depend on an executable from a package (via
        -- @build-tools@), we should solve for the dependencies of that
        -- package separately (since we're not going to actually try to
        -- link it.)  We qualify for EACH package separately; e.g.,
        -- @'Exe' pn1 pn2@ qualifies the @build-tools@ dependency on
        -- @pn2@ from package @pn1@.  (If we tracked only @pn1@, that
        -- would require a consistent dependency resolution for all
        -- of the depended upon executables from a package; if we
        -- tracked only @pn2@, that would require us to pick only one
        -- version of an executable over the entire install plan.)
      | QualExe PackageName PackageName
      deriving (Qualifier -> Qualifier -> Bool
    (Qualifier -> Qualifier -> Bool)
    -> (Qualifier -> Qualifier -> Bool) -> Eq Qualifier
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Qualifier -> Qualifier -> Bool
    == :: Qualifier -> Qualifier -> Bool
    $c/= :: Qualifier -> Qualifier -> Bool
    /= :: Qualifier -> Qualifier -> Bool
    Eq, Eq Qualifier
    Eq Qualifier =>
    (Qualifier -> Qualifier -> Ordering)
    -> (Qualifier -> Qualifier -> Bool)
    -> (Qualifier -> Qualifier -> Bool)
    -> (Qualifier -> Qualifier -> Bool)
    -> (Qualifier -> Qualifier -> Bool)
    -> (Qualifier -> Qualifier -> Qualifier)
    -> (Qualifier -> Qualifier -> Qualifier)
    -> Ord Qualifier
    Qualifier -> Qualifier -> Bool
    Qualifier -> Qualifier -> Ordering
    Qualifier -> Qualifier -> Qualifier
    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 :: Qualifier -> Qualifier -> Ordering
    compare :: Qualifier -> Qualifier -> Ordering
    $c< :: Qualifier -> Qualifier -> Bool
    < :: Qualifier -> Qualifier -> Bool
    $c<= :: Qualifier -> Qualifier -> Bool
    <= :: Qualifier -> Qualifier -> Bool
    $c> :: Qualifier -> Qualifier -> Bool
    > :: Qualifier -> Qualifier -> Bool
    $c>= :: Qualifier -> Qualifier -> Bool
    >= :: Qualifier -> Qualifier -> Bool
    $cmax :: Qualifier -> Qualifier -> Qualifier
    max :: Qualifier -> Qualifier -> Qualifier
    $cmin :: Qualifier -> Qualifier -> Qualifier
    min :: Qualifier -> Qualifier -> Qualifier
    Ord, Int -> Qualifier -> ShowS
    [Qualifier] -> ShowS
    Qualifier -> String
    (Int -> Qualifier -> ShowS)
    -> (Qualifier -> String)
    -> ([Qualifier] -> ShowS)
    -> Show Qualifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Qualifier -> ShowS
    showsPrec :: Int -> Qualifier -> ShowS
    $cshow :: Qualifier -> String
    show :: Qualifier -> String
    $cshowList :: [Qualifier] -> ShowS
    showList :: [Qualifier] -> ShowS
    Show)

    -- | Pretty-prints a qualifier. The result is either empty or
    -- ends in a period, so it can be prepended onto a package name.
    --
    -- NOTE: the base qualifier is for a dependency _on_ base; the qualifier is
    -- there to make sure different dependencies on base are all independent.
    -- So we want to print something like @"A.base"@, where the @"A."@ part
    -- is the qualifier and @"base"@ is the actual dependency (which, for the
    -- 'Base' qualifier, will always be @base@).
    dispQualifier :: Qualifier -> Disp.Doc
    dispQualifier :: Qualifier -> Doc
    dispQualifier Qualifier
    QualToplevel = Doc
    Disp.empty
    dispQualifier (QualSetup PackageName
    pn)  = PackageName -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageName
    pn Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    ":setup."
    dispQualifier (QualExe PackageName
    pn PackageName
    pn2) = PackageName -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageName
    pn Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    ":" Doc -> Doc -> Doc
    <<>>
                                     PackageName -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageName
    pn2 Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    ":exe."
    dispQualifier (QualBase PackageName
    pn)  = PackageName -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageName
    pn Doc -> Doc -> Doc
    <<>> String -> Doc
    Disp.text String
    "."

    -- | A qualified entity. Pairs a package path with the entity.
    data Qualified a = Q PackagePath a
      deriving (Qualified a -> Qualified a -> Bool
    (Qualified a -> Qualified a -> Bool)
    -> (Qualified a -> Qualified a -> Bool) -> Eq (Qualified a)
    forall a. Eq a => Qualified a -> Qualified a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a. Eq a => Qualified a -> Qualified a -> Bool
    == :: Qualified a -> Qualified a -> Bool
    $c/= :: forall a. Eq a => Qualified a -> Qualified a -> Bool
    /= :: Qualified a -> Qualified a -> Bool
    Eq, Eq (Qualified a)
    Eq (Qualified a) =>
    (Qualified a -> Qualified a -> Ordering)
    -> (Qualified a -> Qualified a -> Bool)
    -> (Qualified a -> Qualified a -> Bool)
    -> (Qualified a -> Qualified a -> Bool)
    -> (Qualified a -> Qualified a -> Bool)
    -> (Qualified a -> Qualified a -> Qualified a)
    -> (Qualified a -> Qualified a -> Qualified a)
    -> Ord (Qualified a)
    Qualified a -> Qualified a -> Bool
    Qualified a -> Qualified a -> Ordering
    Qualified a -> Qualified a -> Qualified a
    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
    forall a. Ord a => Eq (Qualified a)
    forall a. Ord a => Qualified a -> Qualified a -> Bool
    forall a. Ord a => Qualified a -> Qualified a -> Ordering
    forall a. Ord a => Qualified a -> Qualified a -> Qualified a
    $ccompare :: forall a. Ord a => Qualified a -> Qualified a -> Ordering
    compare :: Qualified a -> Qualified a -> Ordering
    $c< :: forall a. Ord a => Qualified a -> Qualified a -> Bool
    < :: Qualified a -> Qualified a -> Bool
    $c<= :: forall a. Ord a => Qualified a -> Qualified a -> Bool
    <= :: Qualified a -> Qualified a -> Bool
    $c> :: forall a. Ord a => Qualified a -> Qualified a -> Bool
    > :: Qualified a -> Qualified a -> Bool
    $c>= :: forall a. Ord a => Qualified a -> Qualified a -> Bool
    >= :: Qualified a -> Qualified a -> Bool
    $cmax :: forall a. Ord a => Qualified a -> Qualified a -> Qualified a
    max :: Qualified a -> Qualified a -> Qualified a
    $cmin :: forall a. Ord a => Qualified a -> Qualified a -> Qualified a
    min :: Qualified a -> Qualified a -> Qualified a
    Ord, Int -> Qualified a -> ShowS
    [Qualified a] -> ShowS
    Qualified a -> String
    (Int -> Qualified a -> ShowS)
    -> (Qualified a -> String)
    -> ([Qualified a] -> ShowS)
    -> Show (Qualified a)
    forall a. Show a => Int -> Qualified a -> ShowS
    forall a. Show a => [Qualified a] -> ShowS
    forall a. Show a => Qualified a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Qualified a -> ShowS
    showsPrec :: Int -> Qualified a -> ShowS
    $cshow :: forall a. Show a => Qualified a -> String
    show :: Qualified a -> String
    $cshowList :: forall a. Show a => [Qualified a] -> ShowS
    showList :: [Qualified a] -> ShowS
    Show)

    -- | Qualified package name.
    type QPN = Qualified PackageName

    -- | Pretty-prints a qualified package name.
    dispQPN :: QPN -> Disp.Doc
    dispQPN :: QPN -> Doc
    dispQPN (Q (PackagePath Namespace
    ns Qualifier
    qual) PackageName
    pn) =
      Namespace -> Doc
    dispNamespace Namespace
    ns Doc -> Doc -> Doc
    <<>> Qualifier -> Doc
    dispQualifier Qualifier
    qual Doc -> Doc -> Doc
    <<>> PackageName -> Doc
    forall a. Pretty a => a -> Doc
    pretty PackageName
    pn

    -- | String representation of a qualified package name.
    showQPN :: QPN -> String
    showQPN :: QPN -> String
    showQPN = Style -> Doc -> String
    Disp.renderStyle Style
    flatStyle (Doc -> String) -> (QPN -> Doc) -> QPN -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . QPN -> Doc
    dispQPN