Skip to content
This repository has been archived by the owner on Oct 2, 2020. It is now read-only.

Commit

Permalink
Prefer imports whose package name matches a project namespace
Browse files Browse the repository at this point in the history
A user who creates a logging deftype at
org.mycompany.loggingservices.Logger probably doesn't want to import
java.util.logging.Logger.

The slam.hound.regrow_test.UUID IRecord was changed to conflict with
java.util.TreeSet as this change breaks other tests that did not
anticipate this preference.
  • Loading branch information
guns committed Apr 3, 2014
1 parent f8456cd commit 46c8a9e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 31 deletions.
47 changes: 26 additions & 21 deletions src/slam/hound/regrow.clj
Expand Up @@ -140,6 +140,23 @@
:when alias]
{(symbol alias) #{(symbol var-name)}})))))

(defn- make-munged-ns-pattern [package-name]
(->> (string/split package-name #"_")
(map #(Pattern/quote %))
(string/join "[_-]")
(#(Pattern/compile (str "\\A" % "_*\\z")))))

(defn- find-matching-ns
"Match a Java package name to a Clojure Namespace.
Returns an ns symbol or nil."
[package-name]
;; Try the simple case before doing a search
(let [ns-sym (symbol (string/replace package-name \_ \-))]
(if (find-ns ns-sym)
ns-sym
(let [pat (make-munged-ns-pattern package-name)]
(first (filter #(re-find pat (str %)) (map ns-name (all-ns))))))))

(defn- ns-import-candidates
"Search (all-ns) for imports that match missing-sym, returning a set of
class symbols. This is slower than scanning through the list of static
Expand Down Expand Up @@ -247,13 +264,17 @@
1))))

(defn- is-project-namespace-fn
"Is the namespace defined in a file on the classpath, as opposed to a jar?"
"Is the namespace or class defined in a file on the classpath, as opposed
to a jar?"
[type]
(fn [candidate]
(if (and (contains? #{:alias :refer :rename} type)
(contains? (search/namespaces-from-files) candidate))
0
1)))
(if (= type :import)
(if (find-matching-ns (second (re-find #"(.*)\." (str candidate))))
0
1)
(if (contains? (search/namespaces-from-files) candidate)
0
1))))

(defn- alias-distance [^String alias ^String cand]
(if (= (first alias) (first cand))
Expand Down Expand Up @@ -334,22 +355,6 @@
(or (.isAssignableFrom IType cls)
(.isAssignableFrom IRecord cls)))

(defn- make-munged-ns-pattern [package-name]
(->> (string/split package-name #"_")
(map #(Pattern/quote %))
(string/join "[_-]")
(#(Pattern/compile (str "\\A" % "_*\\z")))))

(defn- find-matching-ns
"Returns a ns symbol or nil"
[package-name]
;; Try the simple case before doing a search
(let [ns-sym (symbol (string/replace package-name \_ \-))]
(if (find-ns ns-sym)
ns-sym
(let [pat (make-munged-ns-pattern package-name)]
(first (filter #(re-find pat (str %)) (map ns-name (all-ns))))))))

(defn- update-imports-in
"Adds candidate to :import entry in ns-map, and also adds matching namespace
to :require if the candidate class was created by deftype or defrecord."
Expand Down
23 changes: 13 additions & 10 deletions test/slam/hound/regrow_test.clj
Expand Up @@ -5,7 +5,7 @@

;; Classes and vars for testing
(defrecord RegrowTestRecord [])
(defrecord UUID [])
(defrecord TreeSet [])
(def +i-must-be-a-cl-user+ true)
(def -+_$?!*><='' :horribly-named-var)
(def / :special-case-token)
Expand All @@ -24,8 +24,8 @@

(deftest ^:unit test-candidates
(testing "finds static and dynamically created Java packages"
(is (= (candidates :import 'UUID '((UUID/randomUUID)) {})
'#{java.util.UUID slam.hound.regrow_test.UUID}))
(is (= (candidates :import 'TreeSet '(TreeSet) {})
'#{java.util.TreeSet slam.hound.regrow_test.TreeSet}))
(is (= (candidates :import 'Compiler$BodyExpr '(Compiler$BodyExpr) {})
'#{clojure.lang.Compiler$BodyExpr}))
(is (= (candidates :import 'RegrowTestRecord '((RegrowTestRecord.)) {})
Expand Down Expand Up @@ -82,11 +82,11 @@
:alias 's
'{:new-ns-map {:alias {clojure.string string}}}))))
(testing "prefers imports from old ns"
(is (= (disambiguate '#{java.util.UUID slam.hound.regrow_test.UUID}
:import 'UUID
(is (= (disambiguate '#{java.util.TreeSet slam.hound.regrow_test.TreeSet}
:import 'TreeSet
'{:old-ns-map
{:import #{slam.hound.regrow_test.UUID}}})
'[:import slam.hound.regrow_test.UUID])))
{:import #{java.util.TreeSet}}})
'[:import java.util.TreeSet])))
(testing "prefers aliases from old ns"
(is (= (disambiguate '#{a zzz} :alias 'x
'{:old-ns-map {:alias {zzz x}}})
Expand All @@ -106,9 +106,12 @@
(is (= (disambiguate '#{clojure.set clojure.string} :alias 'string {})
'[:alias clojure.string])))
(testing "prefers candidates in project namespaces"
(is (= (disambiguate
'#{clojure.string slam.hound.regrow-test} :refer 'trim {})
'[:refer slam.hound.regrow-test])))
(is (= (disambiguate '#{clojure.string slam.hound.regrow-test}
:refer 'trim {})
'[:refer slam.hound.regrow-test]))
(is (= (disambiguate '#{java.util.TreeSet slam.hound.regrow_test.TreeSet}
:import 'TreeSet {})
'[:import slam.hound.regrow_test.TreeSet])))
(testing "prefers candidates whose initials match the alias"
(is (= (disambiguate '#{xray.yankee.zulu abc} :alias 'xyz {})
'[:alias xray.yankee.zulu])))
Expand Down

0 comments on commit 46c8a9e

Please sign in to comment.