-----------------------------------------------------------------------------
--
-- Module      :  Distribution.PackageDescription.PrettyPrint
-- Copyright   :  Jürgen Nicklisch-Franken 2010
-- License     :  AllRightsReserved
--
-- Maintainer  : cabal-devel@haskell.org
-- Stability   : provisional
-- Portability : portable
--
-- | Pretty printing for cabal files
--
-----------------------------------------------------------------------------
{- All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of Isaac Jones nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}

module Distribution.PackageDescription.PrettyPrint (
    writeGenericPackageDescription,
    showGenericPackageDescription,
) where

import Distribution.PackageDescription
       ( TestSuite(..), TestSuiteInterface(..), testType
       , SourceRepo(..),
        customFieldsBI, CondTree(..), Condition(..),
        FlagName(..), ConfVar(..), Executable(..), Library(..),
        Flag(..), PackageDescription(..),
        GenericPackageDescription(..))
import Text.PrettyPrint
       (hsep, comma, punctuate, fsep, parens, char, nest, empty,
        isEmpty, ($$), (<+>), colon, (<>), text, vcat, ($+$), Doc, render)
import Distribution.Simple.Utils (writeUTF8File)
import Distribution.ParseUtils (showFreeText, FieldDescr(..))
import Distribution.PackageDescription.Parse (pkgDescrFieldDescrs,binfoFieldDescrs,libFieldDescrs,
       sourceRepoFieldDescrs)
import Distribution.Package (Dependency(..))
import Distribution.Text (Text(..))
import Data.Maybe (isJust, fromJust, isNothing)

indentWith :: Int
indentWith = 4

-- | Recompile with false for regression testing
simplifiedPrinting :: Bool
simplifiedPrinting = False :: BoolFalse

-- | Writes a .cabal file from a generic package description
writeGenericPackageDescription :: FilePath -> GenericPackageDescription -> IO ()
writeGenericPackageDescription fpath pkg = writeUTF8File :: FilePath -> String -> IO ()writeUTF8File fpath :: FilePathfpath (showGenericPackageDescription ::
  GenericPackageDescription -> StringshowGenericPackageDescription pkg :: GenericPackageDescriptionpkg)

-- | Writes a generic package description to a string
showGenericPackageDescription :: GenericPackageDescription -> String
showGenericPackageDescription            = render :: Doc -> Stringrender (.) :: (b -> c) -> (a -> b) -> a -> c. ppGenericPackageDescription :: GenericPackageDescription -> DocppGenericPackageDescription

ppGenericPackageDescription :: GenericPackageDescription -> Doc
ppGenericPackageDescription gpd          =
        ppPackageDescription :: PackageDescription -> DocppPackageDescription (packageDescription ::
  GenericPackageDescription -> PackageDescriptionpackageDescription gpd :: GenericPackageDescriptiongpd)
        ($+$) :: Doc -> Doc -> Doc$+$ ppGenPackageFlags :: [Flag] -> DocppGenPackageFlags (genPackageFlags :: GenericPackageDescription -> [Flag]genPackageFlags gpd :: GenericPackageDescriptiongpd)
        ($+$) :: Doc -> Doc -> Doc$+$ ppLibrary :: Maybe (CondTree ConfVar [Dependency] Library) -> DocppLibrary (condLibrary ::
  GenericPackageDescription
  -> Maybe (CondTree ConfVar [Dependency] Library)condLibrary gpd :: GenericPackageDescriptiongpd)
        ($+$) :: Doc -> Doc -> Doc$+$ ppExecutables ::
  [(String, CondTree ConfVar [Dependency] Executable)] -> DocppExecutables (condExecutables ::
  GenericPackageDescription
  -> [(String, CondTree ConfVar [Dependency] Executable)]condExecutables gpd :: GenericPackageDescriptiongpd)
        ($+$) :: Doc -> Doc -> Doc$+$ ppTestSuites ::
  [(String, CondTree ConfVar [Dependency] TestSuite)] -> DocppTestSuites (condTestSuites ::
  GenericPackageDescription
  -> [(String, CondTree ConfVar [Dependency] TestSuite)]condTestSuites gpd :: GenericPackageDescriptiongpd)

ppPackageDescription :: PackageDescription -> Doc
ppPackageDescription pd                  =      ppFields :: [FieldDescr a] -> a -> DocppFields pkgDescrFieldDescrs :: [FieldDescr PackageDescription]pkgDescrFieldDescrs pd :: PackageDescriptionpd
                                                ($+$) :: Doc -> Doc -> Doc$+$ ppCustomFields :: [(String, String)] -> DocppCustomFields (customFieldsPD :: PackageDescription -> [(String, String)]customFieldsPD pd :: PackageDescriptionpd)
                                                ($+$) :: Doc -> Doc -> Doc$+$ ppSourceRepos :: [SourceRepo] -> DocppSourceRepos (sourceRepos :: PackageDescription -> [SourceRepo]sourceRepos pd :: PackageDescriptionpd)

ppSourceRepos :: [SourceRepo] -> Doc
ppSourceRepos []                         = empty :: Docempty
ppSourceRepos (hd:tl)                    = ppSourceRepo :: SourceRepo -> DocppSourceRepo hd :: SourceRepohd ($+$) :: Doc -> Doc -> Doc$+$ ppSourceRepos :: [SourceRepo] -> DocppSourceRepos tl :: [SourceRepo]tl

ppSourceRepo :: SourceRepo -> Doc
ppSourceRepo repo                        =
    emptyLine :: Doc -> DocemptyLine ($) :: (a -> b) -> a -> b$ text :: String -> Doctext "source-repository" (<+>) :: Doc -> Doc -> Doc<+> disp :: Text a => a -> Docdisp (repoKind :: SourceRepo -> RepoKindrepoKind repo :: SourceReporepo) ($+$) :: Doc -> Doc -> Doc$+$
        (nest :: Int -> Doc -> Docnest indentWith :: IntindentWith (ppFields :: [FieldDescr a] -> a -> DocppFields sourceRepoFieldDescrs' :: [FieldDescr SourceRepo]sourceRepoFieldDescrs' repo :: SourceReporepo))
  where
    sourceRepoFieldDescrs' = [fd :: FieldDescr SourceRepofd | fd <- sourceRepoFieldDescrs :: [FieldDescr SourceRepo]sourceRepoFieldDescrs, fieldName :: FieldDescr a -> StringfieldName fd :: FieldDescr SourceRepofd (/=) :: Eq a => a -> a -> Bool/= "kind"]

ppFields :: [FieldDescr a] -> a -> Doc
ppFields fields x                        =
    vcat :: [Doc] -> Docvcat [ ppField :: String -> Doc -> DocppField name :: FlagNamename (getter :: a -> Docgetter x :: ax)
                         | FieldDescr name getter _ <- fields :: [FieldDescr a]fields]

ppField :: String -> Doc -> Doc
ppField name fielddoc | isEmpty :: Doc -> BoolisEmpty fielddoc :: Docfielddoc = empty :: Docempty
                      | otherwise :: Boolotherwise        = text :: String -> Doctext name :: FlagNamename (<>) :: Doc -> Doc -> Doc<> colon :: Doccolon (<+>) :: Doc -> Doc -> Doc<+> fielddoc :: Docfielddoc

ppDiffFields :: [FieldDescr a] -> a -> a -> Doc
ppDiffFields fields x y                  =
    vcat :: [Doc] -> Docvcat [ ppField :: String -> Doc -> DocppField name :: FlagNamename (getter :: a -> Docgetter x :: ax)
                         | FieldDescr name getter _ <- fields :: [FieldDescr a]fields,
                            render :: Doc -> Stringrender (getter :: a -> Docgetter x :: ax) (/=) :: Eq a => a -> a -> Bool/= render :: Doc -> Stringrender (getter :: a -> Docgetter y :: ay)]

ppCustomFields :: [(String,String)] -> Doc
ppCustomFields flds                      = vcat :: [Doc] -> Docvcat [ppCustomField :: (String, String) -> DocppCustomField f :: Stringf | f <- flds :: [Flag]flds]

ppCustomField :: (String,String) -> Doc
ppCustomField (name,val)                 = text :: String -> Doctext name :: FlagNamename (<>) :: Doc -> Doc -> Doc<> colon :: Doccolon (<+>) :: Doc -> Doc -> Doc<+> showFreeText :: String -> DocshowFreeText val :: Stringval

ppGenPackageFlags :: [Flag] -> Doc
ppGenPackageFlags flds                   = vcat :: [Doc] -> Docvcat [ppFlag :: Flag -> DocppFlag f :: Stringf | f <- flds :: [Flag]flds]

ppFlag :: Flag -> Doc
ppFlag (MkFlag name desc dflt manual)    =
    emptyLine :: Doc -> DocemptyLine ($) :: (a -> b) -> a -> b$ text :: String -> Doctext "flag" (<+>) :: Doc -> Doc -> Doc<+> ppFlagName :: FlagName -> DocppFlagName name :: FlagNamename ($+$) :: Doc -> Doc -> Doc$+$
            (nest :: Int -> Doc -> Docnest indentWith :: IntindentWith ((if null :: [a] -> Boolnull desc :: Stringdesc
                                then empty :: Docempty
                                else  text :: String -> Doctext "Description: " (<+>) :: Doc -> Doc -> Doc<+> showFreeText :: String -> DocshowFreeText desc :: Stringdesc) ($+$) :: Doc -> Doc -> Doc$+$
                     (if dflt :: Booldflt then empty :: Docempty else text :: String -> Doctext "Default: False") ($+$) :: Doc -> Doc -> Doc$+$
                     (if manual :: Boolmanual then text :: String -> Doctext "Manual: True" else empty :: Docempty)))

ppLibrary :: (Maybe (CondTree ConfVar [Dependency] Library)) -> Doc
ppLibrary Nothing                        = empty :: Docempty
ppLibrary (Just condTree)                =
    emptyLine :: Doc -> DocemptyLine ($) :: (a -> b) -> a -> b$ text :: String -> Doctext "library" ($+$) :: Doc -> Doc -> Doc$+$ nest :: Int -> Doc -> Docnest indentWith :: IntindentWith (ppCondTree ::
  CondTree ConfVar [Dependency] a
  -> Maybe a
  -> (a -> Maybe a -> Doc)
  -> DocppCondTree condTree :: CondTree ConfVar [Dependency] TestSuitecondTree Nothing :: Maybe aNothing ppLib :: Library -> Maybe Library -> DocppLib)
  where
    ppLib lib Nothing     = ppFields :: [FieldDescr a] -> a -> DocppFields libFieldDescrs :: [FieldDescr Library]libFieldDescrs lib :: Librarylib
                            ($$) :: Doc -> Doc -> Doc$$  ppCustomFields :: [(String, String)] -> DocppCustomFields (customFieldsBI :: BuildInfo -> [(String, String)]customFieldsBI (libBuildInfo :: Library -> BuildInfolibBuildInfo lib :: Librarylib))
    ppLib lib (Just plib) = ppDiffFields :: [FieldDescr a] -> a -> a -> DocppDiffFields libFieldDescrs :: [FieldDescr Library]libFieldDescrs lib :: Librarylib plib :: Libraryplib
                            ($$) :: Doc -> Doc -> Doc$$  ppCustomFields :: [(String, String)] -> DocppCustomFields (customFieldsBI :: BuildInfo -> [(String, String)]customFieldsBI (libBuildInfo :: Library -> BuildInfolibBuildInfo lib :: Librarylib))

ppExecutables :: [(String, CondTree ConfVar [Dependency] Executable)] -> Doc
ppExecutables exes                       =
    vcat :: [Doc] -> Docvcat [emptyLine :: Doc -> DocemptyLine ($) :: (a -> b) -> a -> b$ text :: String -> Doctext ("executable " (++) :: [a] -> [a] -> [a]++ n :: Stringn)
              ($+$) :: Doc -> Doc -> Doc$+$ nest :: Int -> Doc -> Docnest indentWith :: IntindentWith (ppCondTree ::
  CondTree ConfVar [Dependency] a
  -> Maybe a
  -> (a -> Maybe a -> Doc)
  -> DocppCondTree condTree :: CondTree ConfVar [Dependency] TestSuitecondTree Nothing :: Maybe aNothing ppExe :: Executable -> Maybe Executable -> DocppExe)| (n,condTree) <- exes :: [(String, CondTree ConfVar [Dependency] Executable)]exes]
  where
    ppExe (Executable _ modulePath' buildInfo') Nothing =
        (if modulePath' :: FilePathmodulePath' (==) :: Eq a => a -> a -> Bool== "" then empty :: Docempty else text :: String -> Doctext "main-is:" (<+>) :: Doc -> Doc -> Doc<+> text :: String -> Doctext modulePath' :: FilePathmodulePath')
            ($+$) :: Doc -> Doc -> Doc$+$ ppFields :: [FieldDescr a] -> a -> DocppFields binfoFieldDescrs :: [FieldDescr BuildInfo]binfoFieldDescrs buildInfo' :: BuildInfobuildInfo'
            ($+$) :: Doc -> Doc -> Doc$+$  ppCustomFields :: [(String, String)] -> DocppCustomFields (customFieldsBI :: BuildInfo -> [(String, String)]customFieldsBI buildInfo' :: BuildInfobuildInfo')
    ppExe (Executable _ modulePath' buildInfo')
            (Just (Executable _ modulePath2 buildInfo2)) =
            (if modulePath' :: FilePathmodulePath' (==) :: Eq a => a -> a -> Bool== "" (||) :: Bool -> Bool -> Bool|| modulePath' :: FilePathmodulePath' (==) :: Eq a => a -> a -> Bool== modulePath2 :: FilePathmodulePath2
                then empty :: Docempty else text :: String -> Doctext "main-is:" (<+>) :: Doc -> Doc -> Doc<+> text :: String -> Doctext modulePath' :: FilePathmodulePath')
            ($+$) :: Doc -> Doc -> Doc$+$ ppDiffFields :: [FieldDescr a] -> a -> a -> DocppDiffFields binfoFieldDescrs :: [FieldDescr BuildInfo]binfoFieldDescrs buildInfo' :: BuildInfobuildInfo' buildInfo2 :: BuildInfobuildInfo2
            ($+$) :: Doc -> Doc -> Doc$+$ ppCustomFields :: [(String, String)] -> DocppCustomFields (customFieldsBI :: BuildInfo -> [(String, String)]customFieldsBI buildInfo' :: BuildInfobuildInfo')

ppTestSuites :: [(String, CondTree ConfVar [Dependency] TestSuite)] -> Doc
ppTestSuites suites =
    emptyLine :: Doc -> DocemptyLine ($) :: (a -> b) -> a -> b$ vcat :: [Doc] -> Docvcat [     text :: String -> Doctext ("test-suite " (++) :: [a] -> [a] -> [a]++ n :: Stringn)
                       ($+$) :: Doc -> Doc -> Doc$+$ nest :: Int -> Doc -> Docnest indentWith :: IntindentWith (ppCondTree ::
  CondTree ConfVar [Dependency] a
  -> Maybe a
  -> (a -> Maybe a -> Doc)
  -> DocppCondTree condTree :: CondTree ConfVar [Dependency] TestSuitecondTree Nothing :: Maybe aNothing ppTestSuite :: TestSuite -> Maybe TestSuite -> DocppTestSuite)
                     | (n,condTree) <- suites :: [(String, CondTree ConfVar [Dependency] TestSuite)]suites]
  where
    ppTestSuite testsuite Nothing =
                text :: String -> Doctext "type:" (<+>) :: Doc -> Doc -> Doc<+> disp :: Text a => a -> Docdisp (testType :: TestSuite -> TestTypetestType testsuite :: TestSuitetestsuite)
            ($+$) :: Doc -> Doc -> Doc$+$ maybe :: b -> (a -> b) -> Maybe a -> bmaybe empty :: Docempty (\f -> text :: String -> Doctext "main-is:"     (<+>) :: Doc -> Doc -> Doc<+> text :: String -> Doctext f :: Stringf)
                            (testSuiteMainIs :: TestSuite -> Maybe FilePathtestSuiteMainIs testsuite :: TestSuitetestsuite)
            ($+$) :: Doc -> Doc -> Doc$+$ maybe :: b -> (a -> b) -> Maybe a -> bmaybe empty :: Docempty (\m -> text :: String -> Doctext "test-module:" (<+>) :: Doc -> Doc -> Doc<+> disp :: Text a => a -> Docdisp m :: ModuleNamem)
                            (testSuiteModule :: TestSuite -> Maybe ModuleNametestSuiteModule testsuite :: TestSuitetestsuite)
            ($+$) :: Doc -> Doc -> Doc$+$ ppFields :: [FieldDescr a] -> a -> DocppFields binfoFieldDescrs :: [FieldDescr BuildInfo]binfoFieldDescrs (testBuildInfo :: TestSuite -> BuildInfotestBuildInfo testsuite :: TestSuitetestsuite)
            ($+$) :: Doc -> Doc -> Doc$+$ ppCustomFields :: [(String, String)] -> DocppCustomFields (customFieldsBI :: BuildInfo -> [(String, String)]customFieldsBI (testBuildInfo :: TestSuite -> BuildInfotestBuildInfo testsuite :: TestSuitetestsuite))

    ppTestSuite (TestSuite _ _ buildInfo' _)
                    (Just (TestSuite _ _ buildInfo2 _)) =
            ppDiffFields :: [FieldDescr a] -> a -> a -> DocppDiffFields binfoFieldDescrs :: [FieldDescr BuildInfo]binfoFieldDescrs buildInfo' :: BuildInfobuildInfo' buildInfo2 :: BuildInfobuildInfo2
            ($+$) :: Doc -> Doc -> Doc$+$ ppCustomFields :: [(String, String)] -> DocppCustomFields (customFieldsBI :: BuildInfo -> [(String, String)]customFieldsBI buildInfo' :: BuildInfobuildInfo')

    testSuiteMainIs test = case testInterface :: TestSuite -> TestSuiteInterfacetestInterface test :: TestSuitetest of
      TestSuiteExeV10 _ f -> Just :: a -> Maybe aJust f :: Stringf
      _                   -> Nothing :: Maybe aNothing

    testSuiteModule test = case testInterface :: TestSuite -> TestSuiteInterfacetestInterface test :: TestSuitetest of
      TestSuiteLibV09 _ m -> Just :: a -> Maybe aJust m :: ModuleNamem
      _                   -> Nothing :: Maybe aNothing

ppCondition :: Condition ConfVar -> Doc
ppCondition (Var x)                      = ppConfVar :: ConfVar -> DocppConfVar x :: ax
ppCondition (Lit b)                      = text :: String -> Doctext (show :: Show a => a -> Stringshow b :: Boolb)
ppCondition (CNot c)                     = char :: Char -> Docchar '!' (<>) :: Doc -> Doc -> Doc<> (ppCondition :: Condition ConfVar -> DocppCondition c :: Condition ConfVarc)
ppCondition (COr c1 c2)                  = parens :: Doc -> Docparens (hsep :: [Doc] -> Dochsep [ppCondition :: Condition ConfVar -> DocppCondition c1 :: Condition ConfVarc1, text :: String -> Doctext "||"
                                                         (<+>) :: Doc -> Doc -> Doc<+> ppCondition :: Condition ConfVar -> DocppCondition c2 :: Condition ConfVarc2])
ppCondition (CAnd c1 c2)                 = parens :: Doc -> Docparens (hsep :: [Doc] -> Dochsep [ppCondition :: Condition ConfVar -> DocppCondition c1 :: Condition ConfVarc1, text :: String -> Doctext "&&"
                                                         (<+>) :: Doc -> Doc -> Doc<+> ppCondition :: Condition ConfVar -> DocppCondition c2 :: Condition ConfVarc2])
ppConfVar :: ConfVar -> Doc
ppConfVar (OS os)                        = text :: String -> Doctext "os"   (<>) :: Doc -> Doc -> Doc<> parens :: Doc -> Docparens (disp :: Text a => a -> Docdisp os :: OSos)
ppConfVar (Arch arch)                    = text :: String -> Doctext "arch" (<>) :: Doc -> Doc -> Doc<> parens :: Doc -> Docparens (disp :: Text a => a -> Docdisp arch :: Archarch)
ppConfVar (Flag name)                    = text :: String -> Doctext "flag" (<>) :: Doc -> Doc -> Doc<> parens :: Doc -> Docparens (ppFlagName :: FlagName -> DocppFlagName name :: FlagNamename)
ppConfVar (Impl c v)                     = text :: String -> Doctext "impl" (<>) :: Doc -> Doc -> Doc<> parens :: Doc -> Docparens (disp :: Text a => a -> Docdisp c :: Condition ConfVarc (<+>) :: Doc -> Doc -> Doc<+> disp :: Text a => a -> Docdisp v :: VersionRangev)

ppFlagName :: FlagName -> Doc
ppFlagName (FlagName name)               = text :: String -> Doctext name :: FlagNamename

ppCondTree :: CondTree ConfVar [Dependency] a -> Maybe a -> (a -> Maybe a -> Doc) ->  Doc
ppCondTree ct@(CondNode it deps ifs) mbIt ppIt =
    let res = ppDeps :: [Dependency] -> DocppDeps deps :: [Dependency]deps
                ($+$) :: Doc -> Doc -> Doc$+$ (vcat :: [Doc] -> Docvcat ($) :: (a -> b) -> a -> b$ map :: (a -> b) -> [a] -> [b]map ppIf ::
  (Condition ConfVar,
   CondTree ConfVar [Dependency] a,
   Maybe (CondTree ConfVar [Dependency] a))
  -> DocppIf ifs ::
  [(Condition ConfVar,
    CondTree ConfVar [Dependency] a,
    Maybe (CondTree ConfVar [Dependency] a))]ifs)
                ($+$) :: Doc -> Doc -> Doc$+$ ppIt :: a -> Maybe a -> DocppIt it :: ait mbIt :: Maybe ambIt
    in if isJust :: Maybe a -> BoolisJust mbIt :: Maybe ambIt (&&) :: Bool -> Bool -> Bool&& isEmpty :: Doc -> BoolisEmpty res :: Docres
        then ppCondTree ::
  CondTree ConfVar [Dependency] a
  -> Maybe a
  -> (a -> Maybe a -> Doc)
  -> DocppCondTree ct :: CondTree ConfVar [Dependency] act Nothing :: Maybe aNothing ppIt :: a -> Maybe a -> DocppIt
        else res :: Docres
  where
    ppIf (c,thenTree,mElseTree)          =
        ((emptyLine :: Doc -> DocemptyLine ($) :: (a -> b) -> a -> b$ text :: String -> Doctext "if" (<+>) :: Doc -> Doc -> Doc<+> ppCondition :: Condition ConfVar -> DocppCondition c :: Condition ConfVarc) ($$) :: Doc -> Doc -> Doc$$
          nest :: Int -> Doc -> Docnest indentWith :: IntindentWith (ppCondTree ::
  CondTree ConfVar [Dependency] a
  -> Maybe a
  -> (a -> Maybe a -> Doc)
  -> DocppCondTree thenTree :: CondTree ConfVar [Dependency] athenTree
                    (if simplifiedPrinting :: BoolsimplifiedPrinting then (Just :: a -> Maybe aJust it :: ait) else Nothing :: Maybe aNothing) ppIt :: a -> Maybe a -> DocppIt))
        ($+$) :: Doc -> Doc -> Doc$+$ (if isNothing :: Maybe a -> BoolisNothing mElseTree :: Maybe (CondTree ConfVar [Dependency] a)mElseTree
                then empty :: Docempty
                else text :: String -> Doctext "else"
                    ($$) :: Doc -> Doc -> Doc$$ nest :: Int -> Doc -> Docnest indentWith :: IntindentWith (ppCondTree ::
  CondTree ConfVar [Dependency] a
  -> Maybe a
  -> (a -> Maybe a -> Doc)
  -> DocppCondTree (fromJust :: Maybe a -> afromJust mElseTree :: Maybe (CondTree ConfVar [Dependency] a)mElseTree)
                        (if simplifiedPrinting :: BoolsimplifiedPrinting then (Just :: a -> Maybe aJust it :: ait) else Nothing :: Maybe aNothing) ppIt :: a -> Maybe a -> DocppIt))

ppDeps :: [Dependency] -> Doc
ppDeps []                                = empty :: Docempty
ppDeps deps                              =
    text :: String -> Doctext "build-depends:" (<+>) :: Doc -> Doc -> Doc<+> fsep :: [Doc] -> Docfsep (punctuate :: Doc -> [Doc] -> [Doc]punctuate comma :: Doccomma (map :: (a -> b) -> [a] -> [b]map disp :: Text a => a -> Docdisp deps :: [Dependency]deps))

emptyLine :: Doc -> Doc
emptyLine d                              = text :: String -> Doctext " " ($+$) :: Doc -> Doc -> Doc$+$ d :: Docd