Skip to content

Commit

Permalink
linters.unused: account for imported classes
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkam2 authored and vemv committed Mar 17, 2021
1 parent 7672782 commit 6d25d90
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 1 deletion.
7 changes: 7 additions & 0 deletions cases/testcases/unusednsimport/consumer1.clj
@@ -0,0 +1,7 @@
(ns testcases.unusednsimport.consumer1
;; This require is needed to properly import the record below
(:require [testcases.unusednsimport.defrecord])
(:import (testcases.unusednsimport.defrecord A)))

;; Exercises top-level forms:
(A. 1)
8 changes: 8 additions & 0 deletions cases/testcases/unusednsimport/consumer2.clj
@@ -0,0 +1,8 @@
(ns testcases.unusednsimport.consumer2
;; This require is needed to properly import the record below
(:require [testcases.unusednsimport.defrecord])
(:import (testcases.unusednsimport.defrecord A)))

;; Should be deemed unused:
(comment
(A. 1))
9 changes: 9 additions & 0 deletions cases/testcases/unusednsimport/consumer3.clj
@@ -0,0 +1,9 @@
(ns testcases.unusednsimport.consumer3
;; This require is needed to properly import the record below
(:require [testcases.unusednsimport.defrecord])
(:import (testcases.unusednsimport.defrecord A)))

;; Exercises forms nested deep into arbitrary code:
(defn sample []
(for [x [(A. 1)]]
x))
9 changes: 9 additions & 0 deletions cases/testcases/unusednsimport/consumer4.clj
@@ -0,0 +1,9 @@
(ns testcases.unusednsimport.consumer4
;; This require is needed to properly import the record below
(:require [testcases.unusednsimport.defrecord])
(:import (testcases.unusednsimport.defrecord A)))

;; Exercises metadata:
(defn ^A sample []
;; return nil (and not `(A.)` so that we are certain that only metadata is being exercised)
nil)
7 changes: 7 additions & 0 deletions cases/testcases/unusednsimport/consumer5.clj
@@ -0,0 +1,7 @@
(ns testcases.unusednsimport.consumer5
;; This require is needed to properly import the record below
(:require [testcases.unusednsimport.defrecord])
(:import (testcases.unusednsimport.defrecord A)))

;; Exercises simple defs:
(def thing (A. 1))
3 changes: 3 additions & 0 deletions cases/testcases/unusednsimport/defrecord.clj
@@ -0,0 +1,3 @@
(ns testcases.unusednsimport.defrecord)

(defrecord A [a])
17 changes: 16 additions & 1 deletion src/eastwood/linters/unused.clj
Expand Up @@ -63,6 +63,19 @@
(str/replace #"\.[^\.]+$" "")
symbol))

(defn classes-used [asts]
(let [simple-tags (->> asts
(mapcat ast/nodes)
(keep :o-tag))
tags-from-meta (->> asts
(mapcat ast/nodes)
(keep (comp :tag meta :result)))
tags (into simple-tags tags-from-meta)]

(into #{}
(remove nil?)
tags)))

(defn protocols-used [asts]
(->> asts
(mapcat ast/nodes)
Expand Down Expand Up @@ -267,6 +280,7 @@ Example: (all-suffixes [1 2 3])
used-keywords (keywords-used asts)
used-macros (macros-invoked asts)
used-protocols (protocols-used asts)
used-classes (classes-used asts)
;; _ (do
;; (println "dbg: required namespaces:")
;; (pp/pprint required)
Expand Down Expand Up @@ -302,7 +316,8 @@ Example: (all-suffixes [1 2 3])
(map symbol))
(keep #(if-let [n (namespace %)] (symbol n))
used-macros)
(map namespace-for used-protocols)))]
(map namespace-for used-protocols)
(map namespace-for used-classes)))]
(for [ns (set/difference required used-namespaces)]
{:loc loc
:unused-namespace-sym ns
Expand Down
17 changes: 17 additions & 0 deletions test/eastwood/test/linters_test.clj
Expand Up @@ -1708,6 +1708,23 @@ the next."
:line 164, :column 1}
1,
})
;; No faults expected:
(lint-test 'testcases.unusednsimport.consumer1 [:unused-namespaces] default-opts {})
;; Fault expected (since the refered type is in a `comment` form):
(lint-test 'testcases.unusednsimport.consumer2
[:unused-namespaces]
default-opts
{{:linter :unused-namespaces
:msg "Namespace testcases.unusednsimport.defrecord is never used in testcases.unusednsimport.consumer2"
:file "testcases/unusednsimport/consumer2.clj"
:line 1
:column 1} 1})
;; No faults expected:
(lint-test 'testcases.unusednsimport.consumer3 [:unused-namespaces] default-opts {})
;; No faults expected:
(lint-test 'testcases.unusednsimport.consumer4 [:unused-namespaces] default-opts {})
;; No faults expected:
(lint-test 'testcases.unusednsimport.consumer5 [:unused-namespaces] default-opts {})
(lint-test
'testcases.unusednss
[:unused-namespaces :unused-locals]
Expand Down

0 comments on commit 6d25d90

Please sign in to comment.