module Language.Haskell.Formatter.Process.Formatter (Formatter(..), format)
where
import qualified Control.Monad as Monad
import qualified Data.Function as Function
import qualified Language.Haskell.Formatter.ExactCode as ExactCode
import qualified Language.Haskell.Formatter.Process.Code as Code
import qualified Language.Haskell.Formatter.Result as Result
import qualified Language.Haskell.Formatter.Source as Source
class Coded a where
getCode :: a -> Source.Module ()
data Formatter = Formatter{ ::
ExactCode.ExactCode ->
Result.Result Code.CommentableCode,
Formatter
-> LocatableCommentableCode -> Result LocatableCommentableCode
formatActualCode ::
Code.LocatableCommentableCode ->
Result.Result Code.LocatableCommentableCode,
::
Code.LocatableCommentableCode ->
Result.Result Code.LocatableCommentableCode,
::
Code.LocatableCommentableCode ->
Result.Result ExactCode.ExactCode}
instance Coded (Source.Module a) where
getCode :: Module a -> Module ()
getCode = Module a -> Module ()
forall (f :: * -> *) a. Functor f => f a -> f ()
Monad.void
instance Coded ExactCode.ExactCode where
getCode :: ExactCode -> Module ()
getCode = Module SrcSpanInfo -> Module ()
forall a. Coded a => a -> Module ()
getCode (Module SrcSpanInfo -> Module ())
-> (ExactCode -> Module SrcSpanInfo) -> ExactCode -> Module ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExactCode -> Module SrcSpanInfo
ExactCode.actualCode
format :: Formatter -> ExactCode.ExactCode -> Result.Result ExactCode.ExactCode
format :: Formatter -> ExactCode -> Result ExactCode
format Formatter
formatter ExactCode
exact
= do CommentableCode
commentable <- Formatter -> ExactCode -> Result CommentableCode
checkedAttachComments Formatter
formatter ExactCode
exact
LocatableCommentableCode
locatableCommentable <- Module SrcSpanInfo
-> CommentableCode -> Result LocatableCommentableCode
Code.tryZipLocationsComments Module SrcSpanInfo
locatable
CommentableCode
commentable
LocatableCommentableCode
locatableCommentable' <- Formatter
-> LocatableCommentableCode -> Result LocatableCommentableCode
formatActualCode Formatter
formatter LocatableCommentableCode
locatableCommentable
LocatableCommentableCode
locatableCommentable'' <- Formatter
-> LocatableCommentableCode -> Result LocatableCommentableCode
checkedFormatComments Formatter
formatter
LocatableCommentableCode
locatableCommentable'
Formatter -> LocatableCommentableCode -> Result ExactCode
checkedDetachComments Formatter
formatter LocatableCommentableCode
locatableCommentable''
where locatable :: Module SrcSpanInfo
locatable = ExactCode -> Module SrcSpanInfo
ExactCode.actualCode ExactCode
exact
checkedAttachComments ::
Formatter ->
ExactCode.ExactCode ->
Result.Result Code.CommentableCode
Formatter
formatter
= (ExactCode -> Result CommentableCode)
-> String -> ExactCode -> Result CommentableCode
forall a b.
(Coded a, Coded b) =>
(a -> Result b) -> String -> a -> Result b
transformNotes (Formatter -> ExactCode -> Result CommentableCode
attachComments Formatter
formatter) String
message
where message :: String
message = String
"Attaching the comments changed the code itself."
transformNotes ::
(Coded a, Coded b) =>
(a -> Result.Result b) -> String -> a -> Result.Result b
transformNotes :: (a -> Result b) -> String -> a -> Result b
transformNotes a -> Result b
transform = (a -> Result b) -> (a -> b -> Bool) -> String -> a -> Result b
forall a b.
(a -> Result b) -> (a -> b -> Bool) -> String -> a -> Result b
transformWithCheck a -> Result b
transform a -> b -> Bool
forall a a. (Coded a, Coded a) => a -> a -> Bool
assert
where assert :: a -> a -> Bool
assert a
code a
code' = a -> Module ()
forall a. Coded a => a -> Module ()
getCode a
code Module () -> Module () -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Module ()
forall a. Coded a => a -> Module ()
getCode a
code'
transformWithCheck ::
(a -> Result.Result b) ->
(a -> b -> Bool) -> String -> a -> Result.Result b
transformWithCheck :: (a -> Result b) -> (a -> b -> Bool) -> String -> a -> Result b
transformWithCheck a -> Result b
transform a -> b -> Bool
assert String
errorMessage a
input
= do b
output <- a -> Result b
transform a
input
if a -> b -> Bool
assert a
input b
output then b -> Result b
forall (m :: * -> *) a. Monad m => a -> m a
return b
output else
String -> Result b
forall a. String -> Result a
Result.fatalAssertionError String
errorMessage
checkedFormatComments ::
Formatter ->
Code.LocatableCommentableCode ->
Result.Result Code.LocatableCommentableCode
Formatter
formatter = (LocatableCommentableCode -> Result LocatableCommentableCode)
-> (LocatableCommentableCode -> LocatableCommentableCode -> Bool)
-> String
-> LocatableCommentableCode
-> Result LocatableCommentableCode
forall a b.
(a -> Result b) -> (a -> b -> Bool) -> String -> a -> Result b
transformWithCheck LocatableCommentableCode -> Result LocatableCommentableCode
transform LocatableCommentableCode -> LocatableCommentableCode -> Bool
assert String
message
where transform :: LocatableCommentableCode -> Result LocatableCommentableCode
transform = Formatter
-> LocatableCommentableCode -> Result LocatableCommentableCode
formatComments Formatter
formatter
assert :: LocatableCommentableCode -> LocatableCommentableCode -> Bool
assert = (Module SrcSpanInfo -> Module SrcSpanInfo -> Bool)
-> (LocatableCommentableCode -> Module SrcSpanInfo)
-> LocatableCommentableCode
-> LocatableCommentableCode
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
Function.on Module SrcSpanInfo -> Module SrcSpanInfo -> Bool
forall a. Eq a => a -> a -> Bool
(==) LocatableCommentableCode -> Module SrcSpanInfo
Code.dropComments
message :: String
message = String
"Formatting the comments changed more than just the comments."
checkedDetachComments ::
Formatter ->
Code.LocatableCommentableCode ->
Result.Result ExactCode.ExactCode
Formatter
formatter
= (LocatableCommentableCode -> Result ExactCode)
-> String -> LocatableCommentableCode -> Result ExactCode
forall a b.
(Coded a, Coded b) =>
(a -> Result b) -> String -> a -> Result b
transformNotes (Formatter -> LocatableCommentableCode -> Result ExactCode
detachComments Formatter
formatter) String
message
where message :: String
message = String
"Detaching the comments changed the code itself."