[ANN] sniper, emacs assistant for deleting dead code

166 views
Skip to first unread message

Jason Wolfe

unread,
Jul 29, 2015, 2:26:18 PM7/29/15
to Clojure
Inspired by YAGNI, I made this code analyzer and emacs assistant for deleting dead code (and then used it to delete 10% of our codebase):

https://github.com/w01fe/sniper


Motivation:

Over the years we've accumulated lots of dead code mixed into our namespaces, and getting rid of it manually is a painful job. At the same time, a fully automated solution won't work since there are lots of functions that aren't used that we want to keep.

My ideal workflow for this would be a tool-assisted, interactive loop, where:
 1. the tool shows the user a form that appears to be unused (except possibly by tests)
 2. the user decides to keep the form and marks it as used, or deletes it and does accompanying cleanup of the code
 3. the tool updates its internal dependency graph based on the user action, and goes back to (1).

I couldn't find any tools that met these criteria (and worked on our 160KLOC codebase), so I wrote sniper.


Features:

Sniper understands supporting (e.g., test) forms, which behave as weak references, and can also identify dead code cycles (a calls b, b calls a, nothing else calls either) which might appear live from a local perspective.

When you delete a form, if there are supporting forms or forms involved in a reference cycle, sniper walks you through removing this collateral damage as well.

Sniper also caches the results of analysis and the set of forms marked as used, to make picking up where you left off easy and fast.


Etc:

Sniper uses clojure.tools.analyzer.jvm to analyze code.  It's an awesome tool, thanks to the creators/maintainers.   

There are still some classes of forms that sniper doesn't handle correctly, and so it will erroneously mark some forms as unused until you tell it you want to keep them.  

It's mostly a fun project so I don't expect it will work perfectly for everyone, but hopefully it's at least an interesting starting point.  

Its dependency graph may also be useful for other things.  For example, identifying (statically) untested forms would be very easy. 

Raoul Duke

unread,
Jul 29, 2015, 2:32:47 PM7/29/15
to clo...@googlegroups.com
> Inspired by YAGNI, I made this code analyzer and emacs assistant for
> deleting dead code (and then used it to delete 10% of our codebase):


oh, i thought the punch line was it was either going to delete you, or
delete itself ;-)

benedek fazekas

unread,
Jul 30, 2015, 1:26:04 AM7/30/15
to Clojure
hi,

I wonder if you tried clj-refactor which has find usages listing all the usages of your symbol *and* its definition. So if you only find the definition and usages in test that symbol might be candidate for deletion...

dennis zhuang

unread,
Jul 30, 2015, 1:33:17 AM7/30/15
to Clojure
Cool work.

But missing installation or user guide in readme.md? I don't know how to use it in my project. I want to try it.


2015-07-30 13:26 GMT+08:00 benedek fazekas <benedek...@gmail.com>:
hi,

I wonder if you tried clj-refactor which has find usages listing all the usages of your symbol *and* its definition. So if you only find the definition and usages in test that symbol might be candidate for deletion...

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
庄晓丹
Email:        killm...@gmail.com xzh...@avos.com
Site:           http://fnil.net
Twitter:      @killme2008


Jason Wolfe

unread,
Jul 30, 2015, 1:37:49 AM7/30/15
to clo...@googlegroups.com
Didn't realize that existed, thanks!  Looks like it's doing a similar (but more sophisticated) thing to find the references.  But it doesn't look like it has the same graph analysis to understand cyclic references, etc, unless I missed it.  

On Wed, Jul 29, 2015 at 10:26 PM, benedek fazekas <benedek...@gmail.com> wrote:
hi,

I wonder if you tried clj-refactor which has find usages listing all the usages of your symbol *and* its definition. So if you only find the definition and usages in test that symbol might be candidate for deletion...
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/l-lQ4YdONqY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

Jason Wolfe

unread,
Jul 30, 2015, 1:58:45 AM7/30/15
to clo...@googlegroups.com
Thanks for the feedback, I'll update the readme to add that now.  


---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/l-lQ4YdONqY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

benedek fazekas

unread,
Jul 30, 2015, 9:05:55 AM7/30/15
to Clojure, ja...@w01fe.com
> But it doesn't look like it has the same graph analysis to understand cyclic references, etc,

you are right it does not. Wondering if you were interested in adding an API to sniper and publish it on clojars... so we could give a try to do a wrapper around it in refactor-nrepl and perhaps some client code as well in clj-refactor.el

Jason Wolfe

unread,
Jul 31, 2015, 5:19:57 PM7/31/15
to benedek fazekas, Clojure
On Thu, Jul 30, 2015 at 6:05 AM, benedek fazekas
<benedek...@gmail.com> wrote:
>> But it doesn't look like it has the same graph analysis to understand
>> cyclic references, etc,
>
> you are right it does not. Wondering if you were interested in adding an API
> to sniper and publish it on clojars... so we could give a try to do a
> wrapper around it in refactor-nrepl and perhaps some client code as well in
> clj-refactor.el

That would be cool!

There's honestly not too much to it, so the best bet might be to
simply lift the parts of the code that seem useful directly into
clj-refactor -- feel free to do so, and I'm happy to answer questions
if you have them.

Otherwise, what kind of API are you looking for?
Reply all
Reply to author
Forward
0 new messages