fourmolu-0.0.6.0: src/Ormolu/Printer/SpanStream.hs
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- | Build span stream from AST.
module Ormolu.Printer.SpanStream
( SpanStream (..),
mkSpanStream,
)
where
import Data.DList (DList)
import qualified Data.DList as D
import Data.Data (Data)
import Data.Generics (everything, ext2Q)
import Data.List (sortOn)
import Data.Typeable (cast)
import 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 (Eq, Show, Data, Semigroup, Monoid)
-- | Create 'SpanStream' from a data structure containing \"located\"
-- elements.
mkSpanStream ::
Data a =>
-- | Data structure to inspect (AST)
a ->
SpanStream
mkSpanStream a =
SpanStream
. sortOn realSrcSpanStart
. D.toList
$ everything mappend (const mempty `ext2Q` queryLocated) a
where
queryLocated ::
(Data e0) =>
GenLocated e0 e1 ->
DList RealSrcSpan
queryLocated (L mspn _) =
case cast mspn :: Maybe SrcSpan of
Nothing -> mempty
Just (UnhelpfulSpan _) -> mempty
Just (RealSrcSpan spn) -> D.singleton spn