{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} -- | A simpler representation of the original AST. module Language.Haskell.Tools.PrettyPrint.RoseTree where import Control.Exception (Exception(..), throw) import Control.Monad.State (Monad(..), execState, modify) import Language.Haskell.Tools.AST -- | A rose tree containing additional node information data RoseTree st = RoseTree { roseInfo :: RoseSourceInfo st , roseChildren :: [RoseTree st] } -- | Heterogenous representation of source information, for pretty printing data RoseSourceInfo st = RoseSpan (SpanInfo st) | RoseList (ListInfo st) | RoseOptional (OptionalInfo st) -- | Transforms the heterogeneous AST into a homogeneous representation for pretty printing toRoseTree :: (SourceInfoTraversal n) => n dom st -> RoseTree st toRoseTree = (\case (root:_):_ -> root; _ -> pprProblem "toRoseTree: the result has no root") . tail . flip execState [[],[]] . toSrcRoseSt where toSrcRoseSt = sourceInfoTraverseUp (SourceInfoTrf (trf RoseSpan) (trf RoseList) (trf RoseOptional)) desc asc desc = modify ([]:) asc = modify tail trf wrap inf = do modify (\(y : x : xs) -> [] : (RoseTree (wrap inf) (reverse y) : x) : xs) return inf data PrettyPrintProblem = PrettyPrintProblem String deriving Show instance Exception PrettyPrintProblem pprProblem :: String -> a pprProblem = throw . PrettyPrintProblem