module UseCounts.Output ( usageOutput ) where import Data.List import Data.Map.Append.Strict (AppendMap(..)) import qualified Data.Map.Strict as M import Data.Ord (Down(..)) import GHC.Api (Name, pprDefinedAt) import GHC.Output import UseCounts.ProcessHie (UsageCounter, UsageCount(..)) limit :: Int limit :: Int limit = Int 15 usageOutput :: UsageCounter -> SDoc usageOutput :: UsageCounter -> SDoc usageOutput (AppendMap Map Name UsageCount usageCounter) = if forall (t :: * -> *) a. Foldable t => t a -> Int length [SDoc] uses forall a. Ord a => a -> a -> Bool < Int limit then [SDoc] -> SDoc vcat [SDoc] uses else [SDoc] -> SDoc vcat [ String -> SDoc text forall a b. (a -> b) -> a -> b $ forall a. Show a => a -> String show Int limit forall a. [a] -> [a] -> [a] ++ String " Least used definitions:" , [SDoc] -> SDoc vcat forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. Int -> [a] -> [a] take Int limit forall a b. (a -> b) -> a -> b $ forall a. [a] -> [a] reverse [SDoc] uses , String -> SDoc text String "" , String -> SDoc text forall a b. (a -> b) -> a -> b $ forall a. Show a => a -> String show Int limit forall a. [a] -> [a] -> [a] ++ String " Most used definitions:" , [SDoc] -> SDoc vcat forall a b. (a -> b) -> a -> b $ forall a. Int -> [a] -> [a] take Int limit [SDoc] uses ] where uses :: [SDoc] uses = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (forall a b c. (a -> b -> c) -> (a, b) -> c uncurry Name -> UsageCount -> SDoc usageLine) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall b a. Ord b => (a -> b) -> [a] -> [a] sortOn (forall a. a -> Down a Down forall b c a. (b -> c) -> (a -> b) -> a -> c . UsageCount -> Int usages forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a b. (a, b) -> b snd) forall b c a. (b -> c) -> (a -> b) -> a -> c . forall k a. Map k a -> [(k, a)] M.toList forall a b. (a -> b) -> a -> b $ forall a k. (a -> Bool) -> Map k a -> Map k a M.filter UsageCount -> Bool locallyDefined Map Name UsageCount usageCounter usageLine :: Name -> UsageCount -> SDoc usageLine :: Name -> UsageCount -> SDoc usageLine Name name UsageCount usage = let numUses :: Int numUses = UsageCount -> Int usages UsageCount usage u :: SDoc u | Int numUses forall a. Eq a => a -> a -> Bool == Int 1 = String -> SDoc text String "use" | Bool otherwise = String -> SDoc text String "uses" in Name -> SDoc nameOutput Name name SDoc -> SDoc -> SDoc $+$ Int -> SDoc -> SDoc nest Int 2 (PprColour -> SDoc -> SDoc coloured PprColour colCyanFg (forall a. Integral a => a -> SDoc intWithCommas Int numUses) SDoc -> SDoc -> SDoc <+> SDoc u) nameOutput :: Name -> SDoc nameOutput :: Name -> SDoc nameOutput Name name = SDoc nameDoc SDoc -> SDoc -> SDoc <+> SDoc locDoc where nameDoc :: SDoc nameDoc = PprColour -> SDoc -> SDoc coloured PprColour colYellowFg forall a b. (a -> b) -> a -> b $ forall a. Outputable a => a -> SDoc ppr Name name locDoc :: SDoc locDoc = PprColour -> SDoc -> SDoc coloured PprColour colMagentaFg forall b c a. (b -> c) -> (a -> b) -> a -> c . SDoc -> SDoc parens forall a b. (a -> b) -> a -> b $ Name -> SDoc pprDefinedAt Name name