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

-- | Rendering of import and export lists.
module Ormolu.Printer.Meat.ImportExport
  ( p_hsmodExports,
    p_hsmodImport,
    breakIfNotDiffFriendly,
  )
where

import Control.Monad
import qualified Data.Text as T
import GHC.Hs
import GHC.LanguageExtensions.Type
import GHC.Types.SrcLoc
import GHC.Unit.Types
import Ormolu.Config (CommaStyle (..), PrinterOpts (poImportExportCommaStyle), poDiffFriendlyImportExport)
import Ormolu.Printer.Combinators
import Ormolu.Printer.Meat.Common
import Ormolu.Utils (RelativePos (..), attachRelativePos)

{- HLINT ignore "Use camelCase" -}

p_hsmodExports :: [LIE GhcPs] -> R ()
p_hsmodExports :: [LIE GhcPs] -> R ()
p_hsmodExports [] = do
  Text -> R ()
txt Text
"("
  R ()
breakpoint'
  Text -> R ()
txt Text
")"
p_hsmodExports [LIE GhcPs]
xs =
  Bool -> R () -> R ()
parens' Bool
False (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
    Layout
layout <- R Layout
getLayout
    R ()
-> ((RelativePos, GenLocated SrcSpanAnnA (IE GhcPs)) -> R ())
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
-> R ()
forall a. R () -> (a -> R ()) -> [a] -> R ()
sep
      R ()
breakpoint
      (\(RelativePos
p, GenLocated SrcSpanAnnA (IE GhcPs)
l) -> R () -> R ()
sitcc (GenLocated SrcSpanAnnA (IE GhcPs) -> (IE GhcPs -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located GenLocated SrcSpanAnnA (IE GhcPs)
l (Layout -> RelativePos -> IE GhcPs -> R ()
p_lie Layout
layout RelativePos
p)))
      ([LIE GhcPs] -> [(RelativePos, LIE GhcPs)]
attachRelativePos' [LIE GhcPs]
xs)

p_hsmodImport :: ImportDecl GhcPs -> R ()
p_hsmodImport :: ImportDecl GhcPs -> R ()
p_hsmodImport ImportDecl {Bool
Maybe (Bool, XRec GhcPs [LIE GhcPs])
Maybe (XRec GhcPs ModuleName)
Maybe StringLiteral
ImportDeclQualifiedStyle
XRec GhcPs ModuleName
XCImportDecl GhcPs
SourceText
IsBootInterface
ideclExt :: forall pass. ImportDecl pass -> XCImportDecl pass
ideclSourceSrc :: forall pass. ImportDecl pass -> SourceText
ideclName :: forall pass. ImportDecl pass -> XRec pass ModuleName
ideclPkgQual :: forall pass. ImportDecl pass -> Maybe StringLiteral
ideclSource :: forall pass. ImportDecl pass -> IsBootInterface
ideclSafe :: forall pass. ImportDecl pass -> Bool
ideclQualified :: forall pass. ImportDecl pass -> ImportDeclQualifiedStyle
ideclImplicit :: forall pass. ImportDecl pass -> Bool
ideclAs :: forall pass. ImportDecl pass -> Maybe (XRec pass ModuleName)
ideclHiding :: forall pass. ImportDecl pass -> Maybe (Bool, XRec pass [LIE pass])
ideclHiding :: Maybe (Bool, XRec GhcPs [LIE GhcPs])
ideclAs :: Maybe (XRec GhcPs ModuleName)
ideclImplicit :: Bool
ideclQualified :: ImportDeclQualifiedStyle
ideclSafe :: Bool
ideclSource :: IsBootInterface
ideclPkgQual :: Maybe StringLiteral
ideclName :: XRec GhcPs ModuleName
ideclSourceSrc :: SourceText
ideclExt :: XCImportDecl GhcPs
..} = do
  Bool
useQualifiedPost <- Extension -> R Bool
isExtensionEnabled Extension
ImportQualifiedPost
  Text -> R ()
txt Text
"import"
  R ()
space
  Bool -> R () -> R ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (IsBootInterface
ideclSource IsBootInterface -> IsBootInterface -> Bool
forall a. Eq a => a -> a -> Bool
== IsBootInterface
IsBoot) (Text -> R ()
txt Text
"{-# SOURCE #-}")
  R ()
space
  Bool -> R () -> R ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
ideclSafe (Text -> R ()
txt Text
"safe")
  R ()
space
  Bool -> R () -> R ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when
    (ImportDeclQualifiedStyle -> Bool
isImportDeclQualified ImportDeclQualifiedStyle
ideclQualified Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
useQualifiedPost)
    (Text -> R ()
txt Text
"qualified")
  R ()
space
  case Maybe StringLiteral
ideclPkgQual of
    Maybe StringLiteral
Nothing -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    Just StringLiteral
slit -> StringLiteral -> R ()
forall a. Outputable a => a -> R ()
atom StringLiteral
slit
  R ()
space
  R () -> R ()
inci (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
    GenLocated SrcSpanAnnA ModuleName -> (ModuleName -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located XRec GhcPs ModuleName
GenLocated SrcSpanAnnA ModuleName
ideclName ModuleName -> R ()
forall a. Outputable a => a -> R ()
atom
    Bool -> R () -> R ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when
      (ImportDeclQualifiedStyle -> Bool
isImportDeclQualified ImportDeclQualifiedStyle
ideclQualified Bool -> Bool -> Bool
&& Bool
useQualifiedPost)
      (R ()
space R () -> R () -> R ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> R ()
txt Text
"qualified")
    case Maybe (XRec GhcPs ModuleName)
ideclAs of
      Maybe (XRec GhcPs ModuleName)
Nothing -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      Just XRec GhcPs ModuleName
l -> do
        R ()
space
        Text -> R ()
txt Text
"as"
        R ()
space
        GenLocated SrcSpanAnnA ModuleName -> (ModuleName -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located XRec GhcPs ModuleName
GenLocated SrcSpanAnnA ModuleName
l ModuleName -> R ()
forall a. Outputable a => a -> R ()
atom
    R ()
space
    case Maybe (Bool, XRec GhcPs [LIE GhcPs])
ideclHiding of
      Maybe (Bool, XRec GhcPs [LIE GhcPs])
Nothing -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      Just (Bool
hiding, XRec GhcPs [LIE GhcPs]
_) ->
        Bool -> R () -> R ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
hiding (Text -> R ()
txt Text
"hiding")
    case Maybe (Bool, XRec GhcPs [LIE GhcPs])
ideclHiding of
      Maybe (Bool, XRec GhcPs [LIE GhcPs])
Nothing -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      Just (Bool
_, L _ xs) -> do
        R ()
breakIfNotDiffFriendly
        Bool -> R () -> R ()
parens' Bool
True (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
          Layout
layout <- R Layout
getLayout
          R ()
-> ((RelativePos, GenLocated SrcSpanAnnA (IE GhcPs)) -> R ())
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
-> R ()
forall a. R () -> (a -> R ()) -> [a] -> R ()
sep
            R ()
breakpoint
            (\(RelativePos
p, GenLocated SrcSpanAnnA (IE GhcPs)
l) -> R () -> R ()
sitcc (GenLocated SrcSpanAnnA (IE GhcPs) -> (IE GhcPs -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located GenLocated SrcSpanAnnA (IE GhcPs)
l (Layout -> RelativePos -> IE GhcPs -> R ()
p_lie Layout
layout RelativePos
p)))
            ([GenLocated SrcSpanAnnA (IE GhcPs)]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall a. [a] -> [(RelativePos, a)]
attachRelativePos [GenLocated SrcSpanAnnA (IE GhcPs)]
xs)
    R ()
newline

p_lie :: Layout -> RelativePos -> IE GhcPs -> R ()
p_lie :: Layout -> RelativePos -> IE GhcPs -> R ()
p_lie Layout
encLayout RelativePos
relativePos = \case
  IEVar XIEVar GhcPs
NoExtField LIEWrappedName (IdP GhcPs)
l1 ->
    R () -> R ()
withComma (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$
      GenLocated SrcSpanAnnA (IEWrappedName RdrName)
-> (IEWrappedName RdrName -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located LIEWrappedName (IdP GhcPs)
GenLocated SrcSpanAnnA (IEWrappedName RdrName)
l1 IEWrappedName RdrName -> R ()
p_ieWrappedName
  IEThingAbs XIEThingAbs GhcPs
_ LIEWrappedName (IdP GhcPs)
l1 ->
    R () -> R ()
withComma (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$
      GenLocated SrcSpanAnnA (IEWrappedName RdrName)
-> (IEWrappedName RdrName -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located LIEWrappedName (IdP GhcPs)
GenLocated SrcSpanAnnA (IEWrappedName RdrName)
l1 IEWrappedName RdrName -> R ()
p_ieWrappedName
  IEThingAll XIEThingAll GhcPs
_ LIEWrappedName (IdP GhcPs)
l1 -> R () -> R ()
withComma (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
    GenLocated SrcSpanAnnA (IEWrappedName RdrName)
-> (IEWrappedName RdrName -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located LIEWrappedName (IdP GhcPs)
GenLocated SrcSpanAnnA (IEWrappedName RdrName)
l1 IEWrappedName RdrName -> R ()
p_ieWrappedName
    R ()
space
    Text -> R ()
txt Text
"(..)"
  IEThingWith XIEThingWith GhcPs
_ LIEWrappedName (IdP GhcPs)
l1 IEWildcard
w [LIEWrappedName (IdP GhcPs)]
xs -> R () -> R ()
sitcc (R () -> R ()) -> (R () -> R ()) -> R () -> R ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. R () -> R ()
withComma (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
    GenLocated SrcSpanAnnA (IEWrappedName RdrName)
-> (IEWrappedName RdrName -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located LIEWrappedName (IdP GhcPs)
GenLocated SrcSpanAnnA (IEWrappedName RdrName)
l1 IEWrappedName RdrName -> R ()
p_ieWrappedName
    R ()
breakIfNotDiffFriendly
    R () -> R ()
inci (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
      let names :: [R ()]
          names :: [R ()]
names = (IEWrappedName RdrName -> R ())
-> GenLocated SrcSpanAnnA (IEWrappedName RdrName) -> R ()
forall l a. HasSrcSpan l => (a -> R ()) -> GenLocated l a -> R ()
located' IEWrappedName RdrName -> R ()
p_ieWrappedName (GenLocated SrcSpanAnnA (IEWrappedName RdrName) -> R ())
-> [GenLocated SrcSpanAnnA (IEWrappedName RdrName)] -> [R ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [LIEWrappedName (IdP GhcPs)]
[GenLocated SrcSpanAnnA (IEWrappedName RdrName)]
xs
      Bool -> R () -> R ()
parens' Bool
False (R () -> R ()) -> ([R ()] -> R ()) -> [R ()] -> R ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. R () -> (R () -> R ()) -> [R ()] -> R ()
forall a. R () -> (a -> R ()) -> [a] -> R ()
sep R ()
commaDelImportExport R () -> R ()
sitcc ([R ()] -> R ()) -> [R ()] -> R ()
forall a b. (a -> b) -> a -> b
$
        case IEWildcard
w of
          IEWildcard
NoIEWildcard -> [R ()]
names
          IEWildcard Int
n ->
            let ([R ()]
before, [R ()]
after) = Int -> [R ()] -> ([R ()], [R ()])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [R ()]
names
             in [R ()]
before [R ()] -> [R ()] -> [R ()]
forall a. [a] -> [a] -> [a]
++ [Text -> R ()
txt Text
".."] [R ()] -> [R ()] -> [R ()]
forall a. [a] -> [a] -> [a]
++ [R ()]
after
  IEModuleContents XIEModuleContents GhcPs
_ XRec GhcPs ModuleName
l1 -> R () -> R ()
withComma (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
    R () -> R ()
indentDoc (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ GenLocated SrcSpanAnnA ModuleName -> (ModuleName -> R ()) -> R ()
forall l a. HasSrcSpan l => GenLocated l a -> (a -> R ()) -> R ()
located XRec GhcPs ModuleName
GenLocated SrcSpanAnnA ModuleName
l1 ModuleName -> R ()
p_hsmodName
  IEGroup XIEGroup GhcPs
NoExtField Int
n HsDocString
str -> do
    case RelativePos
relativePos of
      RelativePos
SinglePos -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      RelativePos
FirstPos -> () -> R ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      RelativePos
MiddlePos -> R ()
newline
      RelativePos
LastPos -> R ()
newline
      RelativePos
FirstAfterDocPos -> R ()
newline
    R () -> R ()
indentDoc (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ HaddockStyle -> Bool -> LHsDocString -> R ()
p_hsDocString (Int -> HaddockStyle
Asterisk Int
n) Bool
False (HsDocString -> LHsDocString
forall e. e -> Located e
noLoc HsDocString
str)
  IEDoc XIEDoc GhcPs
NoExtField HsDocString
str ->
    R () -> R ()
indentDoc (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$
      HaddockStyle -> Bool -> LHsDocString -> R ()
p_hsDocString HaddockStyle
Pipe Bool
False (HsDocString -> LHsDocString
forall e. e -> Located e
noLoc HsDocString
str)
  IEDocNamed XIEDocNamed GhcPs
NoExtField String
str -> R () -> R ()
indentDoc (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ Text -> R ()
txt (Text -> R ()) -> Text -> R ()
forall a b. (a -> b) -> a -> b
$ Text
"-- $" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack String
str
  where
    -- Add a comma to a import-export list element
    withComma :: R () -> R ()
withComma R ()
m =
      case Layout
encLayout of
        Layout
SingleLine ->
          case RelativePos
relativePos of
            RelativePos
SinglePos -> R () -> R ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void R ()
m
            RelativePos
FirstPos -> R ()
m R () -> R () -> R ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> R ()
comma
            RelativePos
MiddlePos -> R ()
m R () -> R () -> R ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> R ()
comma
            RelativePos
LastPos -> R () -> R ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void R ()
m
            RelativePos
FirstAfterDocPos -> R ()
m R () -> R () -> R ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> R ()
comma
        Layout
MultiLine -> do
          CommaStyle
commaStyle <- (forall (f :: * -> *). PrinterOpts f -> f CommaStyle)
-> R CommaStyle
forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
getPrinterOpt forall (f :: * -> *). PrinterOpts f -> f CommaStyle
poImportExportCommaStyle
          case CommaStyle
commaStyle of
            CommaStyle
Leading ->
              case RelativePos
relativePos of
                RelativePos
FirstPos -> R ()
m
                RelativePos
FirstAfterDocPos -> Int -> R () -> R ()
inciBy Int
2 R ()
m
                RelativePos
SinglePos -> R ()
m
                RelativePos
_ -> R ()
comma R () -> R () -> R ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> R ()
space R () -> R () -> R ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> R ()
m
            CommaStyle
Trailing -> R ()
m R () -> R () -> R ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> R ()
comma
    indentDoc :: R () -> R ()
indentDoc R ()
m = do
      CommaStyle
commaStyle <- (forall (f :: * -> *). PrinterOpts f -> f CommaStyle)
-> R CommaStyle
forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
getPrinterOpt forall (f :: * -> *). PrinterOpts f -> f CommaStyle
poImportExportCommaStyle
      case CommaStyle
commaStyle of
        CommaStyle
Trailing -> R ()
m
        CommaStyle
Leading ->
          case RelativePos
relativePos of
            RelativePos
SinglePos -> R ()
m
            RelativePos
FirstPos -> R ()
m
            RelativePos
_ -> Int -> R () -> R ()
inciBy Int
2 R ()
m

----------------------------------------------------------------------------

-- | Unlike the version in `Ormolu.Utils`, this version handles explicitly leading export documentation
attachRelativePos' :: [LIE GhcPs] -> [(RelativePos, LIE GhcPs)]
attachRelativePos' :: [LIE GhcPs] -> [(RelativePos, LIE GhcPs)]
attachRelativePos' = \case
  [] -> []
  [LIE GhcPs
x] -> [(RelativePos
SinglePos, LIE GhcPs
x)]
  -- Check if leading export is a Doc
  (x :: LIE GhcPs
x@(L _ IEDoc {}) : [LIE GhcPs]
xs) -> (RelativePos
FirstPos, LIE GhcPs
GenLocated SrcSpanAnnA (IE GhcPs)
x) (RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall a. a -> [a] -> [a]
: [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall l pass.
[GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
markDoc [LIE GhcPs]
[GenLocated SrcSpanAnnA (IE GhcPs)]
xs
  (x :: LIE GhcPs
x@(L _ IEGroup {}) : [LIE GhcPs]
xs) -> (RelativePos
FirstPos, LIE GhcPs
GenLocated SrcSpanAnnA (IE GhcPs)
x) (RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall a. a -> [a] -> [a]
: [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall l pass.
[GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
markDoc [LIE GhcPs]
[GenLocated SrcSpanAnnA (IE GhcPs)]
xs
  (x :: LIE GhcPs
x@(L _ IEDocNamed {}) : [LIE GhcPs]
xs) -> (RelativePos
FirstPos, LIE GhcPs
GenLocated SrcSpanAnnA (IE GhcPs)
x) (RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall a. a -> [a] -> [a]
: [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall l pass.
[GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
markDoc [LIE GhcPs]
[GenLocated SrcSpanAnnA (IE GhcPs)]
xs
  (LIE GhcPs
x : [LIE GhcPs]
xs) -> (RelativePos
FirstPos, LIE GhcPs
GenLocated SrcSpanAnnA (IE GhcPs)
x) (RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall a. a -> [a] -> [a]
: [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [(RelativePos, GenLocated SrcSpanAnnA (IE GhcPs))]
forall a. [a] -> [(RelativePos, a)]
markLast [LIE GhcPs]
[GenLocated SrcSpanAnnA (IE GhcPs)]
xs
  where
    -- Mark leading documentation, making sure the first export gets assigned
    -- a `FirstPos`
    markDoc :: [GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
markDoc [] = []
    markDoc [GenLocated l (IE pass)
x] = [(RelativePos
LastPos, GenLocated l (IE pass)
x)]
    markDoc (x :: GenLocated l (IE pass)
x@(L l
_ IEDoc {}) : [GenLocated l (IE pass)]
xs) = (RelativePos
FirstAfterDocPos, GenLocated l (IE pass)
x) (RelativePos, GenLocated l (IE pass))
-> [(RelativePos, GenLocated l (IE pass))]
-> [(RelativePos, GenLocated l (IE pass))]
forall a. a -> [a] -> [a]
: [GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
markDoc [GenLocated l (IE pass)]
xs
    markDoc (x :: GenLocated l (IE pass)
x@(L l
_ IEGroup {}) : [GenLocated l (IE pass)]
xs) = (RelativePos
FirstAfterDocPos, GenLocated l (IE pass)
x) (RelativePos, GenLocated l (IE pass))
-> [(RelativePos, GenLocated l (IE pass))]
-> [(RelativePos, GenLocated l (IE pass))]
forall a. a -> [a] -> [a]
: [GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
markDoc [GenLocated l (IE pass)]
xs
    markDoc (x :: GenLocated l (IE pass)
x@(L l
_ IEDocNamed {}) : [GenLocated l (IE pass)]
xs) = (RelativePos
FirstAfterDocPos, GenLocated l (IE pass)
x) (RelativePos, GenLocated l (IE pass))
-> [(RelativePos, GenLocated l (IE pass))]
-> [(RelativePos, GenLocated l (IE pass))]
forall a. a -> [a] -> [a]
: [GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
markDoc [GenLocated l (IE pass)]
xs
    -- First export after a Doc gets assigned a `FirstPos`
    markDoc (GenLocated l (IE pass)
x : [GenLocated l (IE pass)]
xs) = (RelativePos
FirstAfterDocPos, GenLocated l (IE pass)
x) (RelativePos, GenLocated l (IE pass))
-> [(RelativePos, GenLocated l (IE pass))]
-> [(RelativePos, GenLocated l (IE pass))]
forall a. a -> [a] -> [a]
: [GenLocated l (IE pass)] -> [(RelativePos, GenLocated l (IE pass))]
forall a. [a] -> [(RelativePos, a)]
markLast [GenLocated l (IE pass)]
xs

    markLast :: [b] -> [(RelativePos, b)]
markLast [] = []
    markLast [b
x] = [(RelativePos
LastPos, b
x)]
    markLast (b
x : [b]
xs) = (RelativePos
MiddlePos, b
x) (RelativePos, b) -> [(RelativePos, b)] -> [(RelativePos, b)]
forall a. a -> [a] -> [a]
: [b] -> [(RelativePos, b)]
markLast [b]
xs

-- | Surround given entity by parentheses @(@ and @)@.
parens' :: Bool -> R () -> R ()
parens' :: Bool -> R () -> R ()
parens' Bool
topLevelImport R ()
m =
  (forall (f :: * -> *). PrinterOpts f -> f Bool) -> R Bool
forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
getPrinterOpt forall (f :: * -> *). PrinterOpts f -> f Bool
poDiffFriendlyImportExport R Bool -> (Bool -> R ()) -> R ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Bool
True -> do
      Text -> R ()
txt Text
"("
      R ()
breakpoint'
      R () -> R ()
sitcc R ()
body
      R () -> R () -> R ()
forall a. R a -> R a -> R a
vlayout (Text -> R ()
txt Text
")") (Int -> R () -> R ()
inciByFrac (-Int
1) R ()
trailingParen)
    Bool
False -> R () -> R ()
sitcc (R () -> R ()) -> R () -> R ()
forall a b. (a -> b) -> a -> b
$ do
      Text -> R ()
txt Text
"("
      R ()
body
      Text -> R ()
txt Text
")"
  where
    body :: R ()
body = R () -> R () -> R ()
forall a. R a -> R a -> R a
vlayout R ()
singleLine R ()
multiLine
    singleLine :: R ()
singleLine = R ()
m
    multiLine :: R ()
multiLine = do
      CommaStyle
commaStyle <- (forall (f :: * -> *). PrinterOpts f -> f CommaStyle)
-> R CommaStyle
forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
getPrinterOpt forall (f :: * -> *). PrinterOpts f -> f CommaStyle
poImportExportCommaStyle
      case CommaStyle
commaStyle of
        -- On leading commas, list elements are inline with the enclosing parentheses
        CommaStyle
Leading -> do
          R ()
space
          R ()
m
          R ()
newline
        -- On trailing commas, list elements are indented
        CommaStyle
Trailing -> do
          R ()
space
          R () -> R ()
sitcc R ()
m
          R ()
newline
    trailingParen :: R ()
trailingParen = if Bool
topLevelImport then Text -> R ()
txt Text
" )" else Text -> R ()
txt Text
")"

breakIfNotDiffFriendly :: R ()
breakIfNotDiffFriendly :: R ()
breakIfNotDiffFriendly =
  (forall (f :: * -> *). PrinterOpts f -> f Bool) -> R Bool
forall a. (forall (f :: * -> *). PrinterOpts f -> f a) -> R a
getPrinterOpt forall (f :: * -> *). PrinterOpts f -> f Bool
poDiffFriendlyImportExport R Bool -> (Bool -> R ()) -> R ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Bool
True -> R ()
space
    Bool
False -> R ()
breakpoint