{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}
module Graph where
import Control.Arrow
import qualified Data.Graph.Wrapper as Wrapper
import Data.Graph.Wrapper hiding (Graph, toList)
import Data.List
import qualified Data.Set as Set
import Name
import Utils
data Graph a = Graph {
_usageGraph :: [(a, [a])],
classMethodsUsedNames :: [a]
} deriving (Show, Functor)
instance (Ord a) => Eq (Graph a) where
Graph a aUseds == Graph b bUseds =
a === b &&
aUseds === bUseds
where
x === y = sort (nubOrd x) == sort (nubOrd y)
toWrapperGraph :: Ord a => Graph a -> Wrapper.Graph a ()
toWrapperGraph (Graph g _) = fromListLenient $
map (\ (v, outs) -> (v, (), outs)) g
deadNames :: Graph Name -> [Name] -> [Name]
deadNames g@(toWrapperGraph -> graph) roots =
sortTopologically graph $
case map (deadNamesSingle graph) (roots ++ classMethodsUsedNames g) of
(x : xs) -> foldl Set.intersection x xs
[] -> Set.fromList $ vertices graph
deadNamesSingle :: Wrapper.Graph Name () -> Name -> Set.Set Name
deadNamesSingle graph root =
let reachable = Set.fromList $ reachableVertices graph root
allTopLevelDecls = Set.fromList $ vertices graph
in allTopLevelDecls Set.\\ reachable
sortTopologically :: Ord a => Wrapper.Graph a () -> Set.Set a -> [a]
sortTopologically graph set =
filter (`Set.member` set) (topologicalSort graph)
addUsedNames :: Ord a => [a] -> [(a, [a])] -> [(a, [a])]
addUsedNames used = map (second (nubOrd . (++ used)))
withoutUsedNames :: [a] -> [(a, [a])]
withoutUsedNames = map (, [])