    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RecordWildCards #-}

    -- | Rendering of modules.
    module Ormolu.Printer.Meat.Module
      ( p_hsModule,
      )
    where

    import Control.Monad
    import qualified Data.Text as T
    import GHC
    import Ormolu.Imports (normalizeImports)
    import Ormolu.Parser.CommentStream
    import Ormolu.Parser.Pragma
    import Ormolu.Parser.Shebang
    import Ormolu.Printer.Combinators
    import Ormolu.Printer.Comments
    import Ormolu.Printer.Meat.Common
    import Ormolu.Printer.Meat.Declaration
    import Ormolu.Printer.Meat.Declaration.Warning
    import Ormolu.Printer.Meat.ImportExport
    import Ormolu.Printer.Meat.Pragma

    -- | Render a module.
    p_hsModule ::
      -- | Stack header
      Maybe (RealLocated Comment) ->
      -- | Shebangs
      [Shebang] ->
      -- | Pragmas and the associated comments
      [([RealLocated Comment], Pragma)] ->
      -- | Whether to use postfix qualified imports
      Bool ->
      -- | AST to print
      HsModule GhcPs ->
      R ()
    p_hsModule :: Maybe (RealLocated Comment)
    -> [Shebang]
    -> [([RealLocated Comment], Pragma)]
    -> Bool
    -> HsModule GhcPs
    -> R ()
    p_hsModule mstackHeader :: Maybe (RealLocated Comment)
    mstackHeader shebangs :: [Shebang]
    shebangs pragmas :: [([RealLocated Comment], Pragma)]
    pragmas qualifiedPost :: Bool
    qualifiedPost HsModule {..} = do
      let deprecSpan :: [SrcSpan]
    deprecSpan = [SrcSpan]
    -> (Located WarningTxt -> [SrcSpan])
    -> Maybe (Located WarningTxt)
    -> [SrcSpan]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\(L s :: SrcSpan
    s _) -> [SrcSpan
    s]) Maybe (Located WarningTxt)
    hsmodDeprecMessage
          exportSpans :: [SrcSpan]
    exportSpans = [SrcSpan]
    -> (Located [LIE GhcPs] -> [SrcSpan])
    -> Maybe (Located [LIE GhcPs])
    -> [SrcSpan]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (\(L s :: SrcSpan
    s _) -> [SrcSpan
    s]) Maybe (Located [LIE GhcPs])
    hsmodExports
      [SrcSpan] -> R () -> R ()
    switchLayout ([SrcSpan]
    deprecSpan [SrcSpan] -> [SrcSpan] -> [SrcSpan]
    forall a. Semigroup a => a -> a -> a
    <> [SrcSpan]
    exportSpans) (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
        [Shebang] -> (Shebang -> R ()) -> R ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ [Shebang]
    shebangs ((Shebang -> R ()) -> R ()) -> (Shebang -> R ()) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \(Shebang x :: Located String
    x) ->
          Located String -> (String -> R ()) -> R ()
    forall a. Located a -> (a -> R ()) -> R ()
    located Located String
    x ((String -> R ()) -> R ()) -> (String -> R ()) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \shebang :: String
    shebang -> do
            Text -> R ()
    txt (String -> Text
    T.pack String
    shebang)
            R ()
    newline
        Maybe (RealLocated Comment)
    -> (RealLocated Comment -> R ()) -> R ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ Maybe (RealLocated Comment)
    mstackHeader ((RealLocated Comment -> R ()) -> R ())
    -> (RealLocated Comment -> R ()) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \(L spn :: RealSrcSpan
    spn comment :: Comment
    comment) -> do
          RealSrcSpan -> Comment -> R ()
    spitCommentNow RealSrcSpan
    spn Comment
    comment
          R ()
    newline
        R ()
    newline
        [([RealLocated Comment], Pragma)] -> R ()
    p_pragmas [([RealLocated Comment], Pragma)]
    pragmas
        R ()
    newline
        case Maybe (Located ModuleName)
    hsmodName of
          Nothing -> () -> R ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          Just hsmodName' :: Located ModuleName
    hsmodName' -> do
            Located ModuleName -> (ModuleName -> R ()) -> R ()
    forall a. Located a -> (a -> R ()) -> R ()
    located Located ModuleName
    hsmodName' ((ModuleName -> R ()) -> R ()) -> (ModuleName -> R ()) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \name :: ModuleName
    name -> do
              Maybe LHsDocString -> (LHsDocString -> R ()) -> R ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ Maybe LHsDocString
    hsmodHaddockModHeader (HaddockStyle -> Bool -> LHsDocString -> R ()
    p_hsDocString HaddockStyle
    Pipe Bool
    True)
              ModuleName -> R ()
    p_hsmodName ModuleName
    name
            R ()
    breakpoint
            Maybe (Located WarningTxt) -> (Located WarningTxt -> R ()) -> R ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ Maybe (Located WarningTxt)
    hsmodDeprecMessage ((Located WarningTxt -> R ()) -> R ())
    -> (Located WarningTxt -> R ()) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \w :: Located WarningTxt
    w -> do
              (WarningTxt -> R ()) -> Located WarningTxt -> R ()
    forall a. (a -> R ()) -> Located a -> R ()
    located' WarningTxt -> R ()
    p_moduleWarning Located WarningTxt
    w
              R ()
    breakpoint
            case Maybe (Located [LIE GhcPs])
    hsmodExports of
              Nothing -> () -> R ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
              Just l :: Located [LIE GhcPs]
    l -> do
                Located [LIE GhcPs] -> ([LIE GhcPs] -> R ()) -> R ()
    forall a. Located a -> (a -> R ()) -> R ()
    located Located [LIE GhcPs]
    l (([LIE GhcPs] -> R ()) -> R ()) -> ([LIE GhcPs] -> R ()) -> R ()
    forall a b. (a -> b) -> a -> b
    $ \exports :: [LIE GhcPs]
    exports -> do
                  R () -> R ()
    inci ([LIE GhcPs] -> R ()
    p_hsmodExports [LIE GhcPs]
    exports)
                R ()
    breakpoint
            Text -> R ()
    txt "where"
            R ()
    newline
        R ()
    newline
        [LImportDecl GhcPs] -> (LImportDecl GhcPs -> R ()) -> R ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ ([LImportDecl GhcPs] -> [LImportDecl GhcPs]
    normalizeImports [LImportDecl GhcPs]
    hsmodImports) ((ImportDecl GhcPs -> R ()) -> LImportDecl GhcPs -> R ()
    forall a. (a -> R ()) -> Located a -> R ()
    located' (Bool -> ImportDecl GhcPs -> R ()
    p_hsmodImport Bool
    qualifiedPost))
        R ()
    newline
        [SrcSpan] -> R () -> R ()
    switchLayout (LHsDecl GhcPs -> SrcSpan
    forall a. HasSrcSpan a => a -> SrcSpan
    getLoc (LHsDecl GhcPs -> SrcSpan) -> [LHsDecl GhcPs] -> [SrcSpan]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [LHsDecl GhcPs]
    hsmodDecls) (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
          FamilyStyle -> [LHsDecl GhcPs] -> R ()
    p_hsDecls FamilyStyle
    Free [LHsDecl GhcPs]
    hsmodDecls
          R ()
    newline
          R ()
    spitRemainingComments