    -- | Build span stream from AST.
    module Ormolu.Printer.SpanStream
      ( SpanStream (..),
        mkSpanStream,
      )
    where

    import Data.Data (Data)
    import Data.Foldable (toList)
    import Data.Generics (everything, ext1Q, ext2Q)
    import Data.List (sortOn)
    import Data.Maybe (maybeToList)
    import Data.Sequence (Seq)
    import Data.Sequence qualified as Seq
    import Data.Typeable (cast)
    import GHC.Parser.Annotation
    import GHC.Types.SrcLoc

    -- | A stream of 'RealSrcSpan's in ascending order. This allows us to tell
    -- e.g. whether there is another \"located\" element of AST between current
    -- element and comment we're considering for printing.
    newtype SpanStream = SpanStream [RealSrcSpan]
      deriving (SpanStream -> SpanStream -> Bool
    (SpanStream -> SpanStream -> Bool)
    -> (SpanStream -> SpanStream -> Bool) -> Eq SpanStream
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SpanStream -> SpanStream -> Bool
    == :: SpanStream -> SpanStream -> Bool
    $c/= :: SpanStream -> SpanStream -> Bool
    /= :: SpanStream -> SpanStream -> Bool
    Eq, Int -> SpanStream -> ShowS
    [SpanStream] -> ShowS
    SpanStream -> String
    (Int -> SpanStream -> ShowS)
    -> (SpanStream -> String)
    -> ([SpanStream] -> ShowS)
    -> Show SpanStream
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SpanStream -> ShowS
    showsPrec :: Int -> SpanStream -> ShowS
    $cshow :: SpanStream -> String
    show :: SpanStream -> String
    $cshowList :: [SpanStream] -> ShowS
    showList :: [SpanStream] -> ShowS
    Show, Typeable SpanStream
    Typeable SpanStream =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> SpanStream -> c SpanStream)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c SpanStream)
    -> (SpanStream -> Constr)
    -> (SpanStream -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c SpanStream))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c SpanStream))
    -> ((forall b. Data b => b -> b) -> SpanStream -> SpanStream)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> SpanStream -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> SpanStream -> r)
    -> (forall u. (forall d. Data d => d -> u) -> SpanStream -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> SpanStream -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream)
    -> Data SpanStream
    SpanStream -> Constr
    SpanStream -> DataType
    (forall b. Data b => b -> b) -> SpanStream -> SpanStream
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> SpanStream -> u
    forall u. (forall d. Data d => d -> u) -> SpanStream -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SpanStream -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SpanStream -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SpanStream
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> SpanStream -> c SpanStream
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SpanStream)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SpanStream)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> SpanStream -> c SpanStream
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> SpanStream -> c SpanStream
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SpanStream
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SpanStream
    $ctoConstr :: SpanStream -> Constr
    toConstr :: SpanStream -> Constr
    $cdataTypeOf :: SpanStream -> DataType
    dataTypeOf :: SpanStream -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SpanStream)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SpanStream)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SpanStream)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SpanStream)
    $cgmapT :: (forall b. Data b => b -> b) -> SpanStream -> SpanStream
    gmapT :: (forall b. Data b => b -> b) -> SpanStream -> SpanStream
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SpanStream -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SpanStream -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SpanStream -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SpanStream -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> SpanStream -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> SpanStream -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SpanStream -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SpanStream -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SpanStream -> m SpanStream
    Data, NonEmpty SpanStream -> SpanStream
    SpanStream -> SpanStream -> SpanStream
    (SpanStream -> SpanStream -> SpanStream)
    -> (NonEmpty SpanStream -> SpanStream)
    -> (forall b. Integral b => b -> SpanStream -> SpanStream)
    -> Semigroup SpanStream
    forall b. Integral b => b -> SpanStream -> SpanStream
    forall a.
    (a -> a -> a)
    -> (NonEmpty a -> a)
    -> (forall b. Integral b => b -> a -> a)
    -> Semigroup a
    $c<> :: SpanStream -> SpanStream -> SpanStream
    <> :: SpanStream -> SpanStream -> SpanStream
    $csconcat :: NonEmpty SpanStream -> SpanStream
    sconcat :: NonEmpty SpanStream -> SpanStream
    $cstimes :: forall b. Integral b => b -> SpanStream -> SpanStream
    stimes :: forall b. Integral b => b -> SpanStream -> SpanStream
    Semigroup, Semigroup SpanStream
    SpanStream
    Semigroup SpanStream =>
    SpanStream
    -> (SpanStream -> SpanStream -> SpanStream)
    -> ([SpanStream] -> SpanStream)
    -> Monoid SpanStream
    [SpanStream] -> SpanStream
    SpanStream -> SpanStream -> SpanStream
    forall a.
    Semigroup a =>
    a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
    $cmempty :: SpanStream
    mempty :: SpanStream
    $cmappend :: SpanStream -> SpanStream -> SpanStream
    mappend :: SpanStream -> SpanStream -> SpanStream
    $cmconcat :: [SpanStream] -> SpanStream
    mconcat :: [SpanStream] -> SpanStream
    Monoid)

    -- | Create 'SpanStream' from a data structure containing \"located\"
    -- elements.
    mkSpanStream ::
      (Data a) =>
      -- | Data structure to inspect (AST)
      a ->
      SpanStream
    mkSpanStream :: forall a. Data a => a -> SpanStream
    mkSpanStream a
    a =
      [RealSrcSpan] -> SpanStream
    SpanStream
        ([RealSrcSpan] -> SpanStream)
    -> (Seq RealSrcSpan -> [RealSrcSpan])
    -> Seq RealSrcSpan
    -> SpanStream
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (RealSrcSpan -> RealSrcLoc) -> [RealSrcSpan] -> [RealSrcSpan]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    sortOn RealSrcSpan -> RealSrcLoc
    realSrcSpanStart
        ([RealSrcSpan] -> [RealSrcSpan])
    -> (Seq RealSrcSpan -> [RealSrcSpan])
    -> Seq RealSrcSpan
    -> [RealSrcSpan]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Seq RealSrcSpan -> [RealSrcSpan]
    forall a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList
        (Seq RealSrcSpan -> SpanStream) -> Seq RealSrcSpan -> SpanStream
    forall a b. (a -> b) -> a -> b
    $ (Seq RealSrcSpan -> Seq RealSrcSpan -> Seq RealSrcSpan)
    -> GenericQ (Seq RealSrcSpan) -> GenericQ (Seq RealSrcSpan)
    forall r. (r -> r -> r) -> GenericQ r -> GenericQ r
    everything Seq RealSrcSpan -> Seq RealSrcSpan -> Seq RealSrcSpan
    forall a. Monoid a => a -> a -> a
    mappend (Seq RealSrcSpan -> a -> Seq RealSrcSpan
    forall a b. a -> b -> a
    const Seq RealSrcSpan
    forall a. Monoid a => a
    mempty (a -> Seq RealSrcSpan)
    -> (forall d1 d2.
        (Data d1, Data d2) =>
        GenLocated d1 d2 -> Seq RealSrcSpan)
    -> a
    -> Seq RealSrcSpan
    forall d (t :: * -> * -> *) q.
    (Data d, Typeable t) =>
    (d -> q)
    -> (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q) -> d -> q
    `ext2Q` GenLocated d1 d2 -> Seq RealSrcSpan
    forall d1 d2.
    (Data d1, Data d2) =>
    GenLocated d1 d2 -> Seq RealSrcSpan
    forall e0 e1. Data e0 => GenLocated e0 e1 -> Seq RealSrcSpan
    queryLocated (a -> Seq RealSrcSpan)
    -> (forall e. Data e => EpAnn e -> Seq RealSrcSpan)
    -> a
    -> Seq RealSrcSpan
    forall d (t :: * -> *) q.
    (Data d, Typeable t) =>
    (d -> q) -> (forall e. Data e => t e -> q) -> d -> q
    `ext1Q` EpAnn e -> Seq RealSrcSpan
    forall e. Data e => EpAnn e -> Seq RealSrcSpan
    forall ann. EpAnn ann -> Seq RealSrcSpan
    queryEpAnn) a
    a
      where
        queryLocated ::
          (Data e0) =>
          GenLocated e0 e1 ->
          Seq RealSrcSpan
        queryLocated :: forall e0 e1. Data e0 => GenLocated e0 e1 -> Seq RealSrcSpan
    queryLocated (L e0
    mspn e1
    _) =
          Seq RealSrcSpan
    -> (SrcSpan -> Seq RealSrcSpan) -> Maybe SrcSpan -> Seq RealSrcSpan
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Seq RealSrcSpan
    forall a. Monoid a => a
    mempty SrcSpan -> Seq RealSrcSpan
    srcSpanToRealSrcSpanSeq (e0 -> Maybe SrcSpan
    forall a b. (Typeable a, Typeable b) => a -> Maybe b
    cast e0
    mspn :: Maybe SrcSpan)

        queryEpAnn :: EpAnn ann -> Seq RealSrcSpan
        queryEpAnn :: forall ann. EpAnn ann -> Seq RealSrcSpan
    queryEpAnn = SrcSpan -> Seq RealSrcSpan
    srcSpanToRealSrcSpanSeq (SrcSpan -> Seq RealSrcSpan)
    -> (EpAnn ann -> SrcSpan) -> EpAnn ann -> Seq RealSrcSpan
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . EpAnn ann -> SrcSpan
    forall a. HasLoc a => a -> SrcSpan
    locA

        srcSpanToRealSrcSpanSeq :: SrcSpan -> Seq RealSrcSpan
    srcSpanToRealSrcSpanSeq =
          [RealSrcSpan] -> Seq RealSrcSpan
    forall a. [a] -> Seq a
    Seq.fromList ([RealSrcSpan] -> Seq RealSrcSpan)
    -> (SrcSpan -> [RealSrcSpan]) -> SrcSpan -> Seq RealSrcSpan
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe RealSrcSpan -> [RealSrcSpan]
    forall a. Maybe a -> [a]
    maybeToList (Maybe RealSrcSpan -> [RealSrcSpan])
    -> (SrcSpan -> Maybe RealSrcSpan) -> SrcSpan -> [RealSrcSpan]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SrcSpan -> Maybe RealSrcSpan
    srcSpanToRealSrcSpan