{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Floskell.Types
( OutputRestriction(..)
, Penalty(..)
, TabStop(..)
, Printer(..)
, execPrinter
, runPrinter
, PrintState(..)
, psLine
, psColumn
, psNewline
, Style(..)
, FlexConfig(..)
, NodeInfo(..)
, ComInfo(..)
, Location(..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Search
( MonadSearch, Search, runSearchBest )
import Control.Monad.State.Strict
( MonadState(..), StateT, execStateT, runStateT )
import Data.Int ( Int64 )
import Data.Map.Strict ( Map )
import Data.Semigroup as Sem
import Data.Text ( Text )
import Floskell.Buffer ( Buffer )
import qualified Floskell.Buffer as Buffer
import Floskell.Config ( FlexConfig(..), Location(..) )
import Language.Haskell.Exts.Comments
import Language.Haskell.Exts.SrcLoc
data OutputRestriction = Anything | NoOverflow | NoOverflowOrLinebreak
deriving ( Eq, Ord, Show )
newtype Penalty = Penalty Int
deriving ( Eq, Ord, Num, Show )
newtype TabStop = TabStop String
deriving ( Eq, Ord, Show )
instance Sem.Semigroup Penalty where
(<>) = (+)
instance Monoid Penalty where
mempty = 0
#if !(MIN_VERSION_base(4,11,0))
mappend = (<>)
#endif
newtype Printer a =
Printer { unPrinter :: StateT PrintState (Search Penalty) a }
deriving ( Applicative, Monad, Functor, MonadState PrintState
, MonadSearch Penalty, MonadPlus, Alternative )
execPrinter :: Printer a -> PrintState -> Maybe (Penalty, PrintState)
execPrinter m s = runSearchBest $ execStateT (unPrinter m) s
runPrinter :: Printer a -> PrintState -> Maybe (Penalty, (a, PrintState))
runPrinter m s = runSearchBest $ runStateT (unPrinter m) s
data PrintState =
PrintState { psBuffer :: !Buffer
, psIndentLevel :: !Int64
, psOnside :: !Int64
, psTabStops :: !(Map TabStop Int64)
, psUserState :: !FlexConfig
, psEolComment :: !Bool
, psOutputRestriction :: OutputRestriction
}
psLine :: PrintState -> Int64
psLine = Buffer.line . psBuffer
psColumn :: PrintState -> Int64
psColumn = Buffer.column . psBuffer
psNewline :: PrintState -> Bool
psNewline = (== 0) . Buffer.column . psBuffer
data Style =
Style { styleName :: !Text
, styleAuthor :: !Text
, styleDescription :: !Text
, styleInitialState :: !FlexConfig
}
data NodeInfo =
NodeInfo { nodeInfoSpan :: !SrcSpanInfo
, nodeInfoComments :: ![ComInfo]
}
deriving ( Show )
data ComInfo =
ComInfo { comInfoComment :: !Comment
, comInfoLocation :: !(Maybe Location)
}
deriving ( Show )