    {-# LANGUAGE BlockArguments #-}
    {-# LANGUAGE LambdaCase #-}

    -- | Printing of operator trees.
    module Ormolu.Printer.Meat.Declaration.OpTree
      ( p_exprOpTree,
        exprOpTree,
        p_cmdOpTree,
        cmdOpTree,
        p_tyOpTree,
        tyOpTree,
        getOpName,
        getOpNameStr,
      )
    where

    import Data.Functor ((<&>))
    import Data.List.NonEmpty (NonEmpty (..))
    import Data.List.NonEmpty qualified as NE
    import GHC.Hs
    import GHC.Types.Fixity
    import GHC.Types.Name (occNameString)
    import GHC.Types.Name.Reader (RdrName, rdrNameOcc)
    import GHC.Types.SrcLoc
    import Ormolu.Printer.Combinators
    import Ormolu.Printer.Meat.Common (p_rdrName)
    import Ormolu.Printer.Meat.Declaration.Value
      ( IsApplicand (..),
        cmdTopPlacement,
        exprPlacement,
        p_hsCmdTop,
        p_hsExpr,
        p_hsExpr',
      )
    import Ormolu.Printer.Meat.Type (p_hsType)
    import Ormolu.Printer.Operators

    -- | Extract the operator name of the specified 'HsExpr' if this expression
    -- corresponds to an operator.
    getOpName :: HsExpr GhcPs -> Maybe RdrName
    getOpName :: HsExpr GhcPs -> Maybe RdrName
    getOpName = \case
      HsVar XVar GhcPs
    _ (L SrcSpanAnnN
    _ RdrName
    a) -> RdrName -> Maybe RdrName
    forall a. a -> Maybe a
    Just RdrName
    a
      HsExpr GhcPs
    _ -> Maybe RdrName
    forall a. Maybe a
    Nothing

    -- | Convert an operator name to a 'String'.
    getOpNameStr :: RdrName -> String
    getOpNameStr :: RdrName -> String
    getOpNameStr = OccName -> String
    occNameString (OccName -> String) -> (RdrName -> OccName) -> RdrName -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . RdrName -> OccName
    rdrNameOcc

    -- | Decide if the operands of an operator chain should be hanging.
    opBranchPlacement ::
      (HasLoc l) =>
      -- | Placer function for nodes
      (ty -> Placement) ->
      -- | first expression of the chain
      OpTree (GenLocated l ty) op ->
      -- | last expression of the chain
      OpTree (GenLocated l ty) op ->
      Placement
    opBranchPlacement :: forall l ty op.
    HasLoc l =>
    (ty -> Placement)
    -> OpTree (GenLocated l ty) op
    -> OpTree (GenLocated l ty) op
    -> Placement
    opBranchPlacement ty -> Placement
    placer OpTree (GenLocated l ty) op
    firstExpr OpTree (GenLocated l ty) op
    lastExpr
      -- If the beginning of the first argument and the last argument starts on
      -- the same line, and the second argument has a hanging form, use hanging
      -- placement.
      | SrcSpan -> Bool
    isOneLineSpan
          ( SrcLoc -> SrcLoc -> SrcSpan
    mkSrcSpan
              (SrcSpan -> SrcLoc
    srcSpanStart (OpTree (GenLocated l ty) op -> SrcSpan
    forall l a b. HasLoc l => OpTree (GenLocated l a) b -> SrcSpan
    opTreeLoc OpTree (GenLocated l ty) op
    firstExpr))
              (SrcSpan -> SrcLoc
    srcSpanStart (OpTree (GenLocated l ty) op -> SrcSpan
    forall l a b. HasLoc l => OpTree (GenLocated l a) b -> SrcSpan
    opTreeLoc OpTree (GenLocated l ty) op
    lastExpr))
          ),
        OpNode (L l
    _ ty
    n) <- OpTree (GenLocated l ty) op
    lastExpr =
          ty -> Placement
    placer ty
    n
      | Bool
    otherwise = Placement
    Normal

    -- | Decide whether to use braces or not based on the layout and placement
    -- of an expression in an infix operator application.
    opBranchBraceStyle :: Placement -> R (R () -> R ())
    opBranchBraceStyle :: Placement -> R (R () -> R ())
    opBranchBraceStyle Placement
    placement =
      R Layout
    getLayout R Layout -> (Layout -> R () -> R ()) -> R (R () -> R ())
    forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
    <&> \case
        Layout
    SingleLine -> R () -> R ()
    useBraces
        Layout
    MultiLine -> case Placement
    placement of
          Placement
    Hanging -> R () -> R ()
    useBraces
          Placement
    Normal -> R () -> R ()
    dontUseBraces

    -- | Convert a 'LHsExpr' containing an operator tree to the 'OpTree'
    -- intermediate representation.
    exprOpTree :: LHsExpr GhcPs -> OpTree (LHsExpr GhcPs) (LHsExpr GhcPs)
    exprOpTree :: LHsExpr GhcPs -> OpTree (LHsExpr GhcPs) (LHsExpr GhcPs)
    exprOpTree (L SrcSpanAnnA
    _ (OpApp XOpApp GhcPs
    _ LHsExpr GhcPs
    x LHsExpr GhcPs
    op LHsExpr GhcPs
    y)) = OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    -> GenLocated SrcSpanAnnA (HsExpr GhcPs)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    forall ty op. OpTree ty op -> op -> OpTree ty op -> OpTree ty op
    BinaryOpBranches (LHsExpr GhcPs -> OpTree (LHsExpr GhcPs) (LHsExpr GhcPs)
    exprOpTree LHsExpr GhcPs
    x) LHsExpr GhcPs
    GenLocated SrcSpanAnnA (HsExpr GhcPs)
    op (LHsExpr GhcPs -> OpTree (LHsExpr GhcPs) (LHsExpr GhcPs)
    exprOpTree LHsExpr GhcPs
    y)
    exprOpTree LHsExpr GhcPs
    n = GenLocated SrcSpanAnnA (HsExpr GhcPs)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    forall ty op. ty -> OpTree ty op
    OpNode LHsExpr GhcPs
    GenLocated SrcSpanAnnA (HsExpr GhcPs)
    n

    -- | Print an operator tree where leaves are values.
    p_exprOpTree ::
      -- | Bracket style to use
      BracketStyle ->
      -- | N-ary 'OpTree' to render, enhanced with information regarding
      -- operator fixity
      OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs)) ->
      R ()
    p_exprOpTree :: BracketStyle
    -> OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs)) -> R ()
    p_exprOpTree BracketStyle
    s (OpNode LHsExpr GhcPs
    x) = GenLocated SrcSpanAnnA (HsExpr GhcPs)
    -> (HsExpr GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located LHsExpr GhcPs
    GenLocated SrcSpanAnnA (HsExpr GhcPs)
    x (IsApplicand -> BracketStyle -> HsExpr GhcPs -> R ()
    p_hsExpr' IsApplicand
    NotApplicand BracketStyle
    s)
    p_exprOpTree BracketStyle
    s t :: OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs))
    t@(OpBranches exprs :: NonEmpty (OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs)))
    exprs@(OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs))
    firstExpr :| [OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs))]
    otherExprs) [OpInfo (LHsExpr GhcPs)]
    ops) = do
      let placement :: Placement
    placement =
            (HsExpr GhcPs -> Placement)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Placement
    forall l ty op.
    HasLoc l =>
    (ty -> Placement)
    -> OpTree (GenLocated l ty) op
    -> OpTree (GenLocated l ty) op
    -> Placement
    opBranchPlacement
              HsExpr GhcPs -> Placement
    exprPlacement
              OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs))
    OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    firstExpr
              ([OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    forall a. HasCallStack => [a] -> a
    last [OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs))]
    [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    otherExprs)
          rightMostNode :: OpTree ty op -> OpTree ty op
    rightMostNode = \case
            n :: OpTree ty op
    n@(OpNode ty
    _) -> OpTree ty op
    n
            OpBranches NonEmpty (OpTree ty op)
    exprs'' [op]
    _ -> OpTree ty op -> OpTree ty op
    rightMostNode (NonEmpty (OpTree ty op) -> OpTree ty op
    forall a. NonEmpty a -> a
    NE.last NonEmpty (OpTree ty op)
    exprs'')
          isDoBlock :: OpTree (GenLocated l (HsExpr p)) op -> Bool
    isDoBlock = \case
            OpNode (L l
    _ (HsDo XDo p
    _ HsDoFlavour
    ctx XRec p [ExprLStmt p]
    _)) -> case HsDoFlavour
    ctx of
              DoExpr Maybe ModuleName
    _ -> Bool
    True
              MDoExpr Maybe ModuleName
    _ -> Bool
    True
              HsDoFlavour
    _ -> Bool
    False
            OpTree (GenLocated l (HsExpr p)) op
    _ -> Bool
    False
          -- Whether we could place the operator in a trailing position,
          -- followed by a breakpoint before the RHS
          couldBeTrailing :: (OpTree (GenLocated l (HsExpr p)) op, OpInfo op) -> Bool
    couldBeTrailing (OpTree (GenLocated l (HsExpr p)) op
    prevExpr, OpInfo op
    opi) =
            -- An operator with fixity InfixR 0, like seq, $, and $ variants,
            -- is required
            FixityApproximation -> Bool
    isHardSplitterOp (OpInfo op -> FixityApproximation
    forall op. OpInfo op -> FixityApproximation
    opiFixityApproximation OpInfo op
    opi)
              -- the LHS must be single-line
              Bool -> Bool -> Bool
    && SrcSpan -> Bool
    isOneLineSpan (OpTree (GenLocated l (HsExpr p)) op -> SrcSpan
    forall l a b. HasLoc l => OpTree (GenLocated l a) b -> SrcSpan
    opTreeLoc OpTree (GenLocated l (HsExpr p)) op
    prevExpr)
              -- can only happen when a breakpoint would have been added anyway
              Bool -> Bool -> Bool
    && Placement
    placement Placement -> Placement -> Bool
    forall a. Eq a => a -> a -> Bool
    == Placement
    Normal
              -- if the node just on the left of the operator (so the rightmost
              -- node of the subtree prevExpr) is a do-block, then we cannot
              -- place the operator in a trailing position (because it would be
              -- read as being part of the do-block)
              Bool -> Bool -> Bool
    && Bool -> Bool
    not (OpTree (GenLocated l (HsExpr p)) op -> Bool
    forall {l} {p} {op}. OpTree (GenLocated l (HsExpr p)) op -> Bool
    isDoBlock (OpTree (GenLocated l (HsExpr p)) op -> Bool)
    -> OpTree (GenLocated l (HsExpr p)) op -> Bool
    forall a b. (a -> b) -> a -> b
    $ OpTree (GenLocated l (HsExpr p)) op
    -> OpTree (GenLocated l (HsExpr p)) op
    forall {ty} {op}. OpTree ty op -> OpTree ty op
    rightMostNode OpTree (GenLocated l (HsExpr p)) op
    prevExpr)
          -- If all operators at the current level match the conditions to be
          -- trailing, then put them in a trailing position
          isTrailing :: Bool
    isTrailing = ((OpTree
        (GenLocated SrcSpanAnnA (HsExpr GhcPs))
        (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
      OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
     -> Bool)
    -> [(OpTree
           (GenLocated SrcSpanAnnA (HsExpr GhcPs))
           (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
         OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
     OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Bool
    forall {l} {p} {op} {op}.
    HasLoc l =>
    (OpTree (GenLocated l (HsExpr p)) op, OpInfo op) -> Bool
    couldBeTrailing ([(OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
       OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
     -> Bool)
    -> [(OpTree
           (GenLocated SrcSpanAnnA (HsExpr GhcPs))
           (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
         OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> Bool
    forall a b. (a -> b) -> a -> b
    $ [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> [OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
    -> [(OpTree
           (GenLocated SrcSpanAnnA (HsExpr GhcPs))
           (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))),
         OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    forall a b. [a] -> [b] -> [(a, b)]
    zip (NonEmpty
      (OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))))
    -> [OpTree
          (GenLocated SrcSpanAnnA (HsExpr GhcPs))
          (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    forall a. NonEmpty a -> [a]
    NE.toList NonEmpty (OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs)))
    NonEmpty
      (OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))))
    exprs) [OpInfo (LHsExpr GhcPs)]
    [OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs))]
    ops
      ub <- if Bool
    isTrailing then (R () -> R ()) -> R (R () -> R ())
    forall a. a -> R a
    forall (m :: * -> *) a. Monad m => a -> m a
    return R () -> R ()
    useBraces else Placement -> R (R () -> R ())
    opBranchBraceStyle Placement
    placement
      let p_x = R () -> R ()
    ub (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ BracketStyle
    -> OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs)) -> R ()
    p_exprOpTree BracketStyle
    s OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs))
    firstExpr
          putOpsExprs OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    prevExpr (OpInfo (GenLocated l (HsExpr GhcPs))
    opi : [OpInfo (GenLocated l (HsExpr GhcPs))]
    ops') (OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr : [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    exprs') = do
            let isLast :: Bool
    isLast = [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    exprs'
                ub' :: R () -> R ()
    ub' = if Bool -> Bool
    not Bool
    isLast then R () -> R ()
    ub else R () -> R ()
    forall a. a -> a
    id
                -- Distinguish holes used in infix notation.
                -- eg. '1 _foo 2' and '1 `_foo` 2'
                opWrapper :: R () -> R ()
    opWrapper = case GenLocated l (HsExpr GhcPs) -> HsExpr GhcPs
    forall l e. GenLocated l e -> e
    unLoc (OpInfo (GenLocated l (HsExpr GhcPs)) -> GenLocated l (HsExpr GhcPs)
    forall op. OpInfo op -> op
    opiOp OpInfo (GenLocated l (HsExpr GhcPs))
    opi) of
                  HsUnboundVar XUnboundVar GhcPs
    _ RdrName
    _ -> R () -> R ()
    backticks
                  HsExpr GhcPs
    _ -> R () -> R ()
    forall a. a -> a
    id
                p_op :: R ()
    p_op = GenLocated l (HsExpr GhcPs) -> (HsExpr GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located (OpInfo (GenLocated l (HsExpr GhcPs)) -> GenLocated l (HsExpr GhcPs)
    forall op. OpInfo op -> op
    opiOp OpInfo (GenLocated l (HsExpr GhcPs))
    opi) (R () -> R ()
    opWrapper (R () -> R ()) -> (HsExpr GhcPs -> R ()) -> HsExpr GhcPs -> R ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HsExpr GhcPs -> R ()
    p_hsExpr)
                p_y :: R ()
    p_y = R () -> R ()
    ub' (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ BracketStyle
    -> OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs)) -> R ()
    p_exprOpTree BracketStyle
    N OpTree (LHsExpr GhcPs) (OpInfo (LHsExpr GhcPs))
    OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr
            if Bool
    isTrailing
              then do
                R ()
    space
                R ()
    p_op
                Placement -> R () -> R ()
    placeHanging
                  -- When we have a chain of trailing operators (staircase style),
                  -- the last operand, when multiline, is allowed to hang
                  -- (ex: do block, lambda...)
                  ( if Bool
    isLast Bool -> Bool -> Bool
    && (Bool -> Bool
    not (Bool -> Bool)
    -> (OpTree
          (GenLocated SrcSpanAnnA (HsExpr GhcPs))
          (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
        -> Bool)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SrcSpan -> Bool
    isOneLineSpan (SrcSpan -> Bool)
    -> (OpTree
          (GenLocated SrcSpanAnnA (HsExpr GhcPs))
          (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
        -> SrcSpan)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> SrcSpan
    forall l a b. HasLoc l => OpTree (GenLocated l a) b -> SrcSpan
    opTreeLoc (OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
     -> Bool)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Bool
    forall a b. (a -> b) -> a -> b
    $ OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr)
                      then (HsExpr GhcPs -> Placement)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> OpTree
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Placement
    forall l ty op.
    HasLoc l =>
    (ty -> Placement)
    -> OpTree (GenLocated l ty) op
    -> OpTree (GenLocated l ty) op
    -> Placement
    opBranchPlacement HsExpr GhcPs -> Placement
    exprPlacement OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    prevExpr OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr
                      else Placement
    Normal
                  )
                  (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
                    R ()
    p_y
                    OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> [OpInfo (GenLocated l (HsExpr GhcPs))]
    -> [OpTree
          (GenLocated SrcSpanAnnA (HsExpr GhcPs))
          (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> R ()
    putOpsExprs OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr [OpInfo (GenLocated l (HsExpr GhcPs))]
    ops' [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    exprs'
              else do
                Placement -> R () -> R ()
    placeHanging Placement
    placement (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
                  R ()
    p_op
                  R ()
    space
                  R ()
    p_y
                OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> [OpInfo (GenLocated l (HsExpr GhcPs))]
    -> [OpTree
          (GenLocated SrcSpanAnnA (HsExpr GhcPs))
          (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> R ()
    putOpsExprs OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr [OpInfo (GenLocated l (HsExpr GhcPs))]
    ops' [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    exprs'
          putOpsExprs OpTree
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    _ [OpInfo (GenLocated l (HsExpr GhcPs))]
    _ [OpTree
       (GenLocated SrcSpanAnnA (HsExpr GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    _ = () -> R ()
    forall a. a -> R a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
      switchLayout [opTreeLoc t] $ do
        p_x
        putOpsExprs firstExpr ops otherExprs

    -- | Convert a 'LHsCmdTop' containing an operator tree to the 'OpTree'
    -- intermediate representation.
    cmdOpTree :: LHsCmdTop GhcPs -> OpTree (LHsCmdTop GhcPs) (LHsExpr GhcPs)
    cmdOpTree :: LHsCmdTop GhcPs -> OpTree (LHsCmdTop GhcPs) (LHsExpr GhcPs)
    cmdOpTree = \case
      (L EpAnnCO
    _ (HsCmdTop XCmdTop GhcPs
    _ (L SrcSpanAnnA
    _ (HsCmdArrForm XCmdArrForm GhcPs
    _ LHsExpr GhcPs
    op LexicalFixity
    Infix [LHsCmdTop GhcPs
    x, LHsCmdTop GhcPs
    y])))) ->
        OpTree
      (GenLocated EpAnnCO (HsCmdTop GhcPs))
      (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    -> GenLocated SrcSpanAnnA (HsExpr GhcPs)
    -> OpTree
         (GenLocated EpAnnCO (HsCmdTop GhcPs))
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    -> OpTree
         (GenLocated EpAnnCO (HsCmdTop GhcPs))
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    forall ty op. OpTree ty op -> op -> OpTree ty op -> OpTree ty op
    BinaryOpBranches (LHsCmdTop GhcPs -> OpTree (LHsCmdTop GhcPs) (LHsExpr GhcPs)
    cmdOpTree LHsCmdTop GhcPs
    x) LHsExpr GhcPs
    GenLocated SrcSpanAnnA (HsExpr GhcPs)
    op (LHsCmdTop GhcPs -> OpTree (LHsCmdTop GhcPs) (LHsExpr GhcPs)
    cmdOpTree LHsCmdTop GhcPs
    y)
      LHsCmdTop GhcPs
    n -> GenLocated EpAnnCO (HsCmdTop GhcPs)
    -> OpTree
         (GenLocated EpAnnCO (HsCmdTop GhcPs))
         (GenLocated SrcSpanAnnA (HsExpr GhcPs))
    forall ty op. ty -> OpTree ty op
    OpNode LHsCmdTop GhcPs
    GenLocated EpAnnCO (HsCmdTop GhcPs)
    n

    -- | Print an operator tree where leaves are commands.
    p_cmdOpTree ::
      -- | Bracket style to use
      BracketStyle ->
      -- | N-ary OpTree to render, enhanced with information regarding operator
      -- fixity
      OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs)) ->
      R ()
    p_cmdOpTree :: BracketStyle
    -> OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs)) -> R ()
    p_cmdOpTree BracketStyle
    s (OpNode LHsCmdTop GhcPs
    x) = GenLocated EpAnnCO (HsCmdTop GhcPs)
    -> (HsCmdTop GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located LHsCmdTop GhcPs
    GenLocated EpAnnCO (HsCmdTop GhcPs)
    x (BracketStyle -> HsCmdTop GhcPs -> R ()
    p_hsCmdTop BracketStyle
    s)
    p_cmdOpTree BracketStyle
    s t :: OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs))
    t@(OpBranches (OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs))
    firstExpr :| [OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs))]
    otherExprs) [OpInfo (LHsExpr GhcPs)]
    ops) = do
      let placement :: Placement
    placement =
            (HsCmdTop GhcPs -> Placement)
    -> OpTree
         (GenLocated EpAnnCO (HsCmdTop GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> OpTree
         (GenLocated EpAnnCO (HsCmdTop GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    -> Placement
    forall l ty op.
    HasLoc l =>
    (ty -> Placement)
    -> OpTree (GenLocated l ty) op
    -> OpTree (GenLocated l ty) op
    -> Placement
    opBranchPlacement
              HsCmdTop GhcPs -> Placement
    cmdTopPlacement
              OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs))
    OpTree
      (GenLocated EpAnnCO (HsCmdTop GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    firstExpr
              ([OpTree
       (GenLocated EpAnnCO (HsCmdTop GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> OpTree
         (GenLocated EpAnnCO (HsCmdTop GhcPs))
         (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    forall a. HasCallStack => [a] -> a
    last [OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs))]
    [OpTree
       (GenLocated EpAnnCO (HsCmdTop GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    otherExprs)
      ub <- Placement -> R (R () -> R ())
    opBranchBraceStyle Placement
    placement
      let p_x = R () -> R ()
    ub (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ BracketStyle
    -> OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs)) -> R ()
    p_cmdOpTree BracketStyle
    s OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs))
    firstExpr
          putOpsExprs (OpInfo (GenLocated l (HsExpr GhcPs))
    opi : [OpInfo (GenLocated l (HsExpr GhcPs))]
    ops') (OpTree
      (GenLocated EpAnnCO (HsCmdTop GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr : [OpTree
       (GenLocated EpAnnCO (HsCmdTop GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    exprs') = do
            let ub' :: R () -> R ()
    ub' = if Bool -> Bool
    not ([OpTree
       (GenLocated EpAnnCO (HsCmdTop GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [OpTree
       (GenLocated EpAnnCO (HsCmdTop GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    exprs') then R () -> R ()
    ub else R () -> R ()
    forall a. a -> a
    id
                p_op :: R ()
    p_op = GenLocated l (HsExpr GhcPs) -> (HsExpr GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located (OpInfo (GenLocated l (HsExpr GhcPs)) -> GenLocated l (HsExpr GhcPs)
    forall op. OpInfo op -> op
    opiOp OpInfo (GenLocated l (HsExpr GhcPs))
    opi) HsExpr GhcPs -> R ()
    p_hsExpr
                p_y :: R ()
    p_y = R () -> R ()
    ub' (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ BracketStyle
    -> OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs)) -> R ()
    p_cmdOpTree BracketStyle
    N OpTree (LHsCmdTop GhcPs) (OpInfo (LHsExpr GhcPs))
    OpTree
      (GenLocated EpAnnCO (HsCmdTop GhcPs))
      (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
    expr
            Placement -> R () -> R ()
    placeHanging Placement
    placement (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
              R ()
    p_op
              R ()
    space
              R ()
    p_y
            [OpInfo (GenLocated l (HsExpr GhcPs))]
    -> [OpTree
          (GenLocated EpAnnCO (HsCmdTop GhcPs))
          (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    -> R ()
    putOpsExprs [OpInfo (GenLocated l (HsExpr GhcPs))]
    ops' [OpTree
       (GenLocated EpAnnCO (HsCmdTop GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    exprs'
          putOpsExprs [OpInfo (GenLocated l (HsExpr GhcPs))]
    _ [OpTree
       (GenLocated EpAnnCO (HsCmdTop GhcPs))
       (OpInfo (GenLocated SrcSpanAnnA (HsExpr GhcPs)))]
    _ = () -> R ()
    forall a. a -> R a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
      switchLayout [opTreeLoc t] $ do
        p_x
        putOpsExprs ops otherExprs

    -- | Check if given expression has a hanging form. Added for symmetry with
    -- exprPlacement and cmdTopPlacement, which are all used in p_xxxOpTree
    -- functions with opBranchPlacement.
    tyOpPlacement :: HsType GhcPs -> Placement
    tyOpPlacement :: HsType GhcPs -> Placement
    tyOpPlacement = \case
      HsType GhcPs
    _ -> Placement
    Normal

    -- | Convert a LHsType containing an operator tree to the 'OpTree'
    -- intermediate representation.
    tyOpTree :: LHsType GhcPs -> OpTree (LHsType GhcPs) (LocatedN RdrName)
    tyOpTree :: LHsType GhcPs
    -> OpTree (LHsType GhcPs) (GenLocated SrcSpanAnnN RdrName)
    tyOpTree (L SrcSpanAnnA
    _ (HsOpTy XOpTy GhcPs
    _ PromotionFlag
    _ LHsType GhcPs
    l LIdP GhcPs
    op LHsType GhcPs
    r)) =
      OpTree
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (GenLocated SrcSpanAnnN RdrName)
    -> GenLocated SrcSpanAnnN RdrName
    -> OpTree
         (GenLocated SrcSpanAnnA (HsType GhcPs))
         (GenLocated SrcSpanAnnN RdrName)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsType GhcPs))
         (GenLocated SrcSpanAnnN RdrName)
    forall ty op. OpTree ty op -> op -> OpTree ty op -> OpTree ty op
    BinaryOpBranches (LHsType GhcPs
    -> OpTree (LHsType GhcPs) (GenLocated SrcSpanAnnN RdrName)
    tyOpTree LHsType GhcPs
    l) LIdP GhcPs
    GenLocated SrcSpanAnnN RdrName
    op (LHsType GhcPs
    -> OpTree (LHsType GhcPs) (GenLocated SrcSpanAnnN RdrName)
    tyOpTree LHsType GhcPs
    r)
    tyOpTree LHsType GhcPs
    n = GenLocated SrcSpanAnnA (HsType GhcPs)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsType GhcPs))
         (GenLocated SrcSpanAnnN RdrName)
    forall ty op. ty -> OpTree ty op
    OpNode LHsType GhcPs
    GenLocated SrcSpanAnnA (HsType GhcPs)
    n

    -- | Print an operator tree where leaves are types.
    p_tyOpTree ::
      -- | N-ary 'OpTree' to render, enhanced with information regarding
      -- operator fixity
      OpTree (LHsType GhcPs) (OpInfo (LocatedN RdrName)) ->
      R ()
    p_tyOpTree :: OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    -> R ()
    p_tyOpTree (OpNode LHsType GhcPs
    n) = GenLocated SrcSpanAnnA (HsType GhcPs)
    -> (HsType GhcPs -> R ()) -> R ()
    forall l a. HasLoc l => GenLocated l a -> (a -> R ()) -> R ()
    located LHsType GhcPs
    GenLocated SrcSpanAnnA (HsType GhcPs)
    n HsType GhcPs -> R ()
    p_hsType
    p_tyOpTree t :: OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    t@(OpBranches (OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    firstExpr :| [OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    otherExprs) [OpInfo (GenLocated SrcSpanAnnN RdrName)]
    ops) = do
      let placement :: Placement
    placement =
            (HsType GhcPs -> Placement)
    -> OpTree
         (GenLocated SrcSpanAnnA (HsType GhcPs))
         (OpInfo (GenLocated SrcSpanAnnN RdrName))
    -> OpTree
         (GenLocated SrcSpanAnnA (HsType GhcPs))
         (OpInfo (GenLocated SrcSpanAnnN RdrName))
    -> Placement
    forall l ty op.
    HasLoc l =>
    (ty -> Placement)
    -> OpTree (GenLocated l ty) op
    -> OpTree (GenLocated l ty) op
    -> Placement
    opBranchPlacement
              HsType GhcPs -> Placement
    tyOpPlacement
              OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    OpTree
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (OpInfo (GenLocated SrcSpanAnnN RdrName))
    firstExpr
              ([OpTree
       (GenLocated SrcSpanAnnA (HsType GhcPs))
       (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    -> OpTree
         (GenLocated SrcSpanAnnA (HsType GhcPs))
         (OpInfo (GenLocated SrcSpanAnnN RdrName))
    forall a. HasCallStack => [a] -> a
    last [OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    [OpTree
       (GenLocated SrcSpanAnnA (HsType GhcPs))
       (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    otherExprs)
          p_x :: R ()
    p_x = OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    -> R ()
    p_tyOpTree OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    firstExpr
          putOpsExprs :: [OpInfo (GenLocated SrcSpanAnnN RdrName)]
    -> [OpTree
          (GenLocated SrcSpanAnnA (HsType GhcPs))
          (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    -> R ()
    putOpsExprs (OpInfo (GenLocated SrcSpanAnnN RdrName)
    opi : [OpInfo (GenLocated SrcSpanAnnN RdrName)]
    ops') (OpTree
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (OpInfo (GenLocated SrcSpanAnnN RdrName))
    expr : [OpTree
       (GenLocated SrcSpanAnnA (HsType GhcPs))
       (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    exprs') = do
            let p_op :: R ()
    p_op = GenLocated SrcSpanAnnN RdrName -> R ()
    p_rdrName (OpInfo (GenLocated SrcSpanAnnN RdrName)
    -> GenLocated SrcSpanAnnN RdrName
    forall op. OpInfo op -> op
    opiOp OpInfo (GenLocated SrcSpanAnnN RdrName)
    opi)
                p_y :: R ()
    p_y = OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    -> R ()
    p_tyOpTree OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    OpTree
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (OpInfo (GenLocated SrcSpanAnnN RdrName))
    expr
            Placement -> R () -> R ()
    placeHanging
              Placement
    placement
              (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
                R ()
    p_op
                R ()
    space
                R ()
    p_y
            [OpInfo (GenLocated SrcSpanAnnN RdrName)]
    -> [OpTree
          (GenLocated SrcSpanAnnA (HsType GhcPs))
          (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    -> R ()
    putOpsExprs [OpInfo (GenLocated SrcSpanAnnN RdrName)]
    ops' [OpTree
       (GenLocated SrcSpanAnnA (HsType GhcPs))
       (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    exprs'
          putOpsExprs [OpInfo (GenLocated SrcSpanAnnN RdrName)]
    _ [OpTree
       (GenLocated SrcSpanAnnA (HsType GhcPs))
       (OpInfo (GenLocated SrcSpanAnnN RdrName))]
    _ = () -> R ()
    forall a. a -> R a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
      [SrcSpan] -> R () -> R ()
    switchLayout [OpTree
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (OpInfo (GenLocated SrcSpanAnnN RdrName))
    -> SrcSpan
    forall l a b. HasLoc l => OpTree (GenLocated l a) b -> SrcSpan
    opTreeLoc OpTree (LHsType GhcPs) (OpInfo (GenLocated SrcSpanAnnN RdrName))
    OpTree
      (GenLocated SrcSpanAnnA (HsType GhcPs))
      (OpInfo (GenLocated SrcSpanAnnN RdrName))
    t] (R () -> R ()) -> R () -> R ()
    forall a b. (a -> b) -> a -> b
    $ do
        ub <- Placement -> R (R () -> R ())
    opBranchBraceStyle Placement
    placement
        ub p_x
        putOpsExprs ops otherExprs