Permalink
Browse files

First cut at unused locals

  • Loading branch information...
1 parent ddf76e7 commit 84ae56c42ca4be212e78f3b1b358782839464301 @jonase committed Jan 14, 2012
Showing with 57 additions and 3 deletions.
  1. +4 −0 src/brittle/core.clj
  2. +6 −3 src/eastwood/core.clj
  3. +26 −0 src/eastwood/linters/unused.clj
  4. +21 −0 src/eastwood/util.clj
View
@@ -14,6 +14,10 @@
(replicate 1 0) ; deprecated
(.length s))
+(defn foo [x] ; <- never used
+ (let [a 0 x 1] ; <- a is never used
+ x))
+
(defn hour [] ;; Deprecated x 2!
View
@@ -5,7 +5,8 @@
[clojure.string :as string]
[clojure.set :as set]
[eastwood.linters.core :as linters]
- [eastwood.linters.deprecated :as deprecated]))
+ [eastwood.linters.deprecated :as deprecated]
+ [eastwood.linters.unused :as unused]))
(defn analyze [ns-sym]
@@ -21,7 +22,9 @@
:misplaced-docstrings linters/misplaced-docstrings
;:non-dynamic-earmuffs linters/non-dynamic-earmuffs ;checked by compiler
:reflection linters/reflection
- :deprecations deprecated/deprecations})
+ :deprecations deprecated/deprecations
+ :unused-locals unused/unused-locals
+ })
(def ^:private all-linters (set (keys linters)))
@@ -36,4 +39,4 @@
(doseq [ns namespaces]
(lint exprs ns))))
-;(lint-ns 'brittle.core :only [:deprecations])
+;(lint-ns 'brittle.core :only [:unused-locals])
@@ -0,0 +1,26 @@
+(ns eastwood.linters.unused
+ (:require [clojure.set :as set]
+ [eastwood.util :as util])
+ (:use analyze.core analyze.util))
+
+(defn unused-locals* [binding-expr]
+ (let [lbs (util/local-bindings binding-expr)
+ free (apply set/union (map util/free-locals
+ (:children binding-expr)))]
+ (set/difference lbs free)))
+
+(defn binding-expr? [expr]
+ (#{:let :let-fn :fn-method} (:op expr)))
+
+(defn report [locals]
+ ;; TODO: Line numbers?
+ (println "Bindings" locals "are never used"))
+
+(defn unused-locals [exprs]
+ (doseq [expr (mapcat expr-seq exprs)]
+ (if (and (binding-expr? expr))
+ (when-let [ul (seq (for [{sym :sym} (unused-locals* expr)
+ :when (not= '_ sym)]
+ sym))]
+ (report ul)))))
+
View
@@ -0,0 +1,21 @@
+(ns eastwood.util
+ (:require [clojure.set :as set]))
+
+(defn local-bindings [expr]
+ (condp = (:op expr)
+ :fn-method (if-let [rest-param (:rest-param expr)]
+ (conj (set (:required-params expr)) rest-param)
+ (set (:required-params expr)))
+ :let (set (map :local-binding (:binding-inits expr)))
+ :let-fn (set (map :local-binding (:binding-inits expr)))
+ #{}))
+
+
+(defn free-locals [expr]
+ (if (= (:op expr) :local-binding-expr)
+ #{(:local-binding expr)}
+ (set/difference (apply set/union (map free-locals
+ (:children expr)))
+ (local-bindings expr))))
+
+

0 comments on commit 84ae56c

Please sign in to comment.