{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Retrie.ExactPrint.Annotated
(
Annotated
, astA
, annsA
, seedA
, AnnotatedHsDecl
, AnnotatedHsExpr
, AnnotatedHsType
, AnnotatedImport
, AnnotatedImports
, AnnotatedModule
, AnnotatedPat
, AnnotatedStmt
, pruneA
, graftA
, transformA
, trimA
, printA
, unsafeMkA
) where
import Control.Monad.State.Lazy hiding (fix)
import Data.Default as D
import Data.Functor.Identity
import Language.Haskell.GHC.ExactPrint hiding
( cloneT
, setEntryDP
, setEntryDPT
, transferEntryDPT
, transferEntryDP
)
import Language.Haskell.GHC.ExactPrint.Annotate (Annotate)
import Language.Haskell.GHC.ExactPrint.Types (emptyAnns)
import Retrie.GHC
import Retrie.SYB
type AnnotatedHsDecl = Annotated (LHsDecl GhcPs)
type AnnotatedHsExpr = Annotated (LHsExpr GhcPs)
type AnnotatedHsType = Annotated (LHsType GhcPs)
type AnnotatedImport = Annotated (LImportDecl GhcPs)
type AnnotatedImports = Annotated [LImportDecl GhcPs]
type AnnotatedModule = Annotated (Located (HsModule GhcPs))
type AnnotatedPat = Annotated (Located (Pat GhcPs))
type AnnotatedStmt = Annotated (LStmt GhcPs (LHsExpr GhcPs))
data Annotated ast = Annotated
{ astA :: ast
, annsA :: Anns
, seedA :: Int
}
instance Functor Annotated where
fmap f Annotated{..} = Annotated{astA = f astA, ..}
instance Foldable Annotated where
foldMap f = f . astA
instance Traversable Annotated where
traverse f Annotated{..} =
(\ast -> Annotated{astA = ast, ..}) <$> f astA
instance Default ast => Default (Annotated ast) where
def = Annotated D.def emptyAnns 0
instance (Data ast, Monoid ast) => Semigroup (Annotated ast) where
(<>) = mappend
instance (Data ast, Monoid ast) => Monoid (Annotated ast) where
mempty = Annotated mempty emptyAnns 0
mappend a1 (Annotated ast2 anns _) =
runIdentity $ transformA a1 $ \ ast1 ->
mappend ast1 <$> graftT anns ast2
unsafeMkA :: ast -> Anns -> Int -> Annotated ast
unsafeMkA = Annotated
transformA
:: Monad m => Annotated ast1 -> (ast1 -> TransformT m ast2) -> m (Annotated ast2)
transformA (Annotated ast anns seed) f = do
(ast',(anns',seed'),_) <- runTransformFromT seed anns (f ast)
return $ Annotated ast' anns' seed'
graftA :: (Data ast, Monad m) => Annotated ast -> TransformT m ast
graftA (Annotated x anns _) = graftT anns x
pruneA :: (Data ast, Monad m) => ast -> TransformT m (Annotated ast)
pruneA ast = Annotated ast <$> getAnnsT <*> gets snd
trimA :: Data ast => Annotated ast -> Annotated ast
trimA = runIdentity . transformA nil . const . graftA
where
nil :: Annotated ()
nil = mempty
printA :: Annotate ast => Annotated (Located ast) -> String
printA (Annotated ast anns _) = exactPrint ast anns