callGraph :: Readable (Local s) => SiteState s -> IO [Node]
callGraph siteState =
  do fs <- listAllFuns siteState
     cs <- mapM (getCalls siteState) fs
     let missing = [ f | c <- cs, f <- c, not (f `elem` fs) ]
         xs     = zip missing (repeat []) ++ zip fs cs
         invMap = Map.fromListWith (++) [ (g,[f]) | (f,gs) <- xs, g <- gs ]
         getCalledBy f = Map.findWithDefault [] f invMap
         stage  = 0 -- Temporary
     return $ setStages
              [ Node { calledBy = getCalledBy fun , ..  } | (fun,calls) <- xs ]



-- | Assumes no loops in the graph (i.e., no recursive functions).
callGraph :: Readable (Local s) => SiteState s -> IO [Node]
callGraph siteState =
  do fs <- listAllFuns siteState
     cs <- mapM (getCalls siteState) fs
     let missing = [ f | c <- cs, f <- c, not (f `elem` fs) ]
         xs     = zip missing (repeat []) ++ zip fs cs
         invMap = Map.fromListWith (++) [ (g,[f]) | (f,gs) <- xs, g <- gs ]
         getCalledBy f = Map.findWithDefault [] f invMap
         stage  = 0 -- Temporary
     return $ setStages
              [ Node { calledBy = getCalledBy fun , ..  } | (fun,calls) <- xs ]



-- | Assumes no loops in the graph (i.e., no recursive functions).
callGraph siteState =
  do fs <- listAllFuns siteState
     cs <- mapM (getCalls siteState) fs
     let missing = [ f | c <- cs, f <- c, not (f `elem` fs) ]
         xs     = zip missing (repeat []) ++ zip fs cs
         invMap = Map.fromListWith (++) [ (g,[f]) | (f,gs) <- xs, g <- gs ]
         getCalledBy f = Map.findWithDefault [] f invMap
         stage  = 0 -- Temporary
     return $ setStages
              [ Node { calledBy = getCalledBy fun , ..  } | (fun,calls) <- xs ]



-- | Assumes no loops in the graph (i.e., no recursive functions).