module Idris.UnusedArgs where
import Idris.AbsSyntax
import Core.CaseTree
import Core.TT
import Control.Monad.State
import Data.Maybe
import Data.List
findUnusedArgs :: [Name] -> Idris ()
findUnusedArgs ns = mapM_ traceUnused ns
traceUnused :: Name -> Idris ()
traceUnused n
= do i <- getIState
case lookupCtxt n (idris_callgraph i) of
[CGInfo args calls scg usedns _] ->
do let argpos = zip args [0..]
let fargs = concatMap (getFargpos calls) argpos
logLvl 3 $ show n ++ " used TRACE: " ++ show fargs
recused <- mapM (\ (argn, i, (g, j)) ->
do u <- used [(n, i)] g j
return (argn, u)) fargs
let fused = nub $ usedns ++ map fst (filter snd recused)
logLvl 1 $ show n ++ " used args: " ++ show fused
let unusedpos = mapMaybe (getUnused fused) (zip [0..] args)
logLvl 1 $ show n ++ " unused args: " ++ show (args, unusedpos)
addToCG n (CGInfo args calls scg usedns unusedpos)
_ -> return ()
where
getUnused fused (i,n) | n `elem` fused = Nothing
| otherwise = Just i
used :: [(Name, Int)] -> Name -> Int -> Idris Bool
used path g j
| (g, j) `elem` path = return False
| otherwise
= do logLvl 5 $ (show ((g, j) : path))
i <- getIState
case lookupCtxt g (idris_callgraph i) of
[CGInfo args calls scg usedns unused] ->
if (j >= length args)
then
return True
else do let directuse = args!!j `elem` usedns
let garg = getFargpos calls (args!!j, j)
logLvl 5 $ show (g, j, garg)
recused <- mapM (\ (argn, j, (g', j')) ->
used ((g,j):path) g' j') garg
return (directuse || null recused || or recused)
_ -> return True
getFargpos :: [(Name, [[Name]])] -> (Name, Int) -> [(Name, Int, (Name, Int))]
getFargpos calls (n, i) = concatMap (getCallArgpos n i) calls
where getCallArgpos :: Name -> Int -> (Name, [[Name]]) ->
[(Name, Int, (Name, Int))]
getCallArgpos n i (g, args)
= let argpos = zip [0..] args in
mapMaybe (\ (j, xs) -> if n `elem` xs then Just (n, i, (g, j))
else Nothing) argpos