[darcs-devel] Dead code
Ian Lynagh
igloo at earth.li
Sat May 14 08:57:01 PDT 2005
Hi all,
Attached is a nasty hack of a script which should find unused functions
(add -ddump-parsed to GHCFLAGS, rebuild and run the script on stdout).
David, nothing seems to use:
instance ReadableDirectory SlurpMonad
instance WriteableDirectory SlurpMonad
Are these now redundant, or are they on the way to being used?
Below is the current script output on my local tree. The ones I've
*ed are ones I think should be kept regardless, because they are part of
a self-contained module, or they complete a set. I haven't done any
digging yet, so there may be others like them. Are there any others we
should keep (or disagreements with keeping the ones I've indicated)?
Note there may be errors as the script is, as I said, a nasty hack :-)
(better scripts welcomed!).
Thanks
Ian
Autoconf.darcsconfdir
DarcsArguments.do_norm
DarcsArguments.gui_interactive
DarcsArguments.gui_pipe_interactive
* DarcsUtils.putDocLnError
* FastPackedString.consPS
* FastPackedString.elemPS
* FastPackedString.foldlPS
* FastPackedString.foldrPS
* FastPackedString.gzWriteFilePS
* FastPackedString.spanPS
* FastPackedString.splitWithPS
* FastPackedString.unpackWords
* FastPackedString.wordsPS
* Lock.appendBinFile
PatchApply.patchChanges
PatchBundle.make_context
PatchCheck.dir_exists
PatchCheck.do_verbose_check
PatchChoices.force_matching_last
PatchCommute.helper_force_commute
PatchInfo.fix_up_fname
PatchInfo.make_alt_filename
PatchInfo.midtrunc
PatchInfo.munge_char
PatchInfo.repopatchinfo
PatchReadMonads.lex_strings
PatchTest.prop_elegant_merge_good_enough
PatchTest.prop_glump_order_independent
PatchTest.prop_glump_seq_merge
PatchTest.prop_glump_seq_merge_valid
PatchTest.prop_glump_three_merge
PatchTest.prop_glump_three_merge_valid
PatchTest.prop_simple_smart_merge_good_enough
PatchTest.prop_unravel_order_independent
PatchTest.simple_smart_merge
PatchTest.smart_merge
PatchTest.verbose_check_a_patch
Population.adjustPopStates
Population.cleanPop
Population.getRepoPop
Population.lookupBy
Population.popUnfold
Population.popUnfoldDirty
PopulationData.notModified
PopulationData.setPopState
PopulationData.setState
* Printer.newline_p
* Printer.putDoc
* Printer.putDocWith
* Printer.space_p
Pristine.getPristinePop
RepoPrefs.set_prefval
Resolution.hand_resolution
SlurpDirectory.readFileLinesPS
-------------- next part --------------
import Control.Monad
import Data.Char
import Data.List
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Maybe
import qualified Data.Set as Set
import Data.Set (Set)
import System.Environment (getArgs)
type Function = String
type Module = String
type UsesMap = Map Function (Set Function)
type DefInMap = Map Function (Set Module)
data State = St { st_uses :: UsesMap,
st_def_in :: DefInMap,
st_mod :: Module,
st_fun :: Maybe Function
}
main :: IO ()
main = do args <- getArgs
let (file, debug) = case args of
[] -> ("-", False)
["debug"] -> ("-", True)
[f] -> (f, False)
[f, "debug"] -> (f, True)
["debug", f] -> (f, True)
_ -> error "Bad arguments"
xs <- if file == "-" then getContents else readFile file
let st = foldl do_line init_state (lines xs)
uses = st_uses st
uses' = foldr del_from uses ["main", "instance", "class"]
def_in = st_def_in st
when debug $ mapM_ print $ Map.assocs uses
mapM_ (putStrLn . show_unused def_in) $ Map.keys uses'
show_unused :: DefInMap -> Function -> String
show_unused def_in f
= case Map.lookup f def_in of
Nothing -> error "Can't happen"
Just ds -> concat $ intersperse ", " $ map (++ "." ++ f) $ Set.toList ds
del_from :: Function -> UsesMap -> UsesMap
del_from x uses = let xs = Set.toList $ fromMaybe Set.empty $ Map.lookup x uses
uses' = Map.delete x uses
in foldr del_from uses' xs
init_state :: State
init_state = St { st_uses = Map.empty,
st_def_in = Map.empty,
st_mod = "",
st_fun = Nothing
}
do_line :: State -> String -> State
do_line st "" = st
do_line st l | "module " `isPrefixOf` l
= st { st_mod = takeWhile is_fun_char (drop (length "module ") l) }
do_line st l
| any (`isPrefixOf` l) ["import ", "infixr ", "infix ",
"infixl ", "newtype ", "type ", "data "]
= st { st_fun = Nothing }
do_line st l
| isLower (head l)
= let d = takeWhile is_fun_char l
def_in = st_def_in st
ms = Set.insert (st_mod st) (Map.findWithDefault Set.empty d def_in)
def_in' = Map.insert d ms def_in
in do_line (st { st_fun = Just d,
st_def_in = def_in'}) (' ':l)
do_line st l
| isJust (st_fun st) && isSpace (head l)
= let fun = fromJust $ st_fun st
uses = st_uses st
x' = Set.fromList (get_uses l) `Set.union`
Map.findWithDefault Set.empty fun uses
uses' = Map.insert fun x' uses
in st {st_uses = uses'}
do_line st _ = st { st_fun = Nothing }
is_fun_char :: Char -> Bool
is_fun_char c = isAlphaNum c || c `elem` "_'"
get_uses :: String -> [Function]
get_uses xs = let xs1 = dropWhile (not . is_fun_char) xs
(xs2, xs3) = span is_fun_char xs1
in if null xs2 then []
else if isLower (head xs2) then xs2:get_uses xs3
else get_uses xs3
More information about the darcs-devel
mailing list