Skip to content

Commit

Permalink
Merge pull request #260 from NoahTheDuke/nb/some-fixes
Browse files Browse the repository at this point in the history
Fixes and clean up
  • Loading branch information
NoahTheDuke authored May 16, 2024
2 parents c456b51 + 86b021e commit a7f77b0
Show file tree
Hide file tree
Showing 25 changed files with 114 additions and 77 deletions.
1 change: 1 addition & 0 deletions .clj-kondo/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{:lint-as {kibit.rules.util/defrules clj-kondo.lint-as/def-catch-all}}
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. This change

## [Unreleased]

* Update to Clojure 1.11 to handle ##Inf etc. [#237](https://github.com/clj-commons/kibit/pull/237)
* Switch to borkdude/edamame for side-effect free parsing. [#235](https://github.com/clj-commons/kibit/pull/235), [#246](https://github.com/clj-commons/kibit/pull/246)
* Correctly gather options-spec require vectors as maps so we can check for :as and :as-alias. [#238](https://github.com/clj-commons/kibit/pull/238)
* Moved all of the test/resources files to a new corpus folder which isn't loaded by default on test runs.

## 0.1.10 / 2024-05-09

* Fix scm information in generated pom.xml.
Expand Down
5 changes: 5 additions & 0 deletions corpus/as_alias.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(ns resources.as-alias
(:require
[foo.bar :a :b :as-alias fb]))

::fb/example
1 change: 1 addition & 0 deletions corpus/double_pound_reader_macros.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[##Inf ##-Inf ##NaN]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions corpus/namespaced_maps.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#:car{:make "Jeep" :model "Wrangler"}
1 change: 1 addition & 0 deletions corpus/read_eval.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(if true (do #=(prn :hello :world!) :a))
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#?(:clj (+ 1 1)
:cljs (+ 2 2)
:default (+ 3 3))

{:a 1 :b 2 #?@(:clj [:c 3 :d 4])}
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 4 additions & 6 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.8.0"}
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
org.clojure/core.logic {:mvn/version "1.1.0"}
org.clojure/tools.cli {:mvn/version "1.1.230"}
org.clojure/tools.reader {:mvn/version "1.4.2"}
borkdude/edamame {:mvn/version "1.4.25"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.47"}}
;; At least Clojure v1.9 is required to run `clojure -X:`. Run this as
;; `clojure -X:exec` or `clojure -X:exec -i -r markdown`, for example.
:aliases {:exec {:extra-deps {org.clojure/clojure {:mvn/version "1.9.0"}
org.babashka/cli {:mvn/version "0.7.51"}}
;; Run this as `clojure -X:exec` or `clojure -X:exec -i -r markdown`, for example.
:aliases {:exec {:extra-deps {org.babashka/cli {:mvn/version "0.7.51"}}
:exec-fn kibit.driver/exec
:exec-args {:paths ["."]}
:main-opts ["-m" "babashka.cli.exec"]}}}
3 changes: 2 additions & 1 deletion lein-kibit/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/tools.namespace "1.5.0"]
[jonase/kibit ~(clojure.string/trim-newline (slurp "../resources/jonase/kibit/VERSION"))]]
:deploy-repositories [["releases" :clojars]
:deploy-repositories [["clojars" {:url "https://clojars.org/repo"
:sign-releases false}]
["snapshots" :clojars]]
:eval-in-leiningen true)
5 changes: 2 additions & 3 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@
:url "https://github.com/clj-commons/kibit"
:connection "scm:git:git://github.com/clj-commons/kibit.git"
:developerConnection "scm:git:ssh://[email protected]/clj-commons/kibit.git"}
:dependencies [[org.clojure/clojure "1.8.0"]
:dependencies [[org.clojure/clojure "1.11.1"]
[org.clojure/core.logic "1.1.0"]
[org.clojure/tools.cli "1.1.230"]
[rewrite-clj "1.1.47"]
[org.clojure/tools.reader "1.4.2"]]
:profiles {:dev {:resource-paths ["test/resources"]}}
[borkdude/edamame "1.4.25"]]
:deploy-repositories [["clojars" {:url "https://clojars.org/repo"
:sign-releases false}]
["snapshots" :clojars]]
Expand Down
19 changes: 7 additions & 12 deletions src/kibit/check.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
(ns kibit.check
"Kibit's integration point and public API"
(:require [clojure.java.io :as io]
[clojure.core.logic.unifier :as unifier]
[kibit.core :as core]
[kibit.rules :as core-rules]
[kibit.reporters :as reporters]
Expand Down Expand Up @@ -67,12 +66,13 @@
"Construct the canonical simplify-map
given an expression and a simplified expression."
[expr simplified-expr]
{:expr expr
:line (-> expr meta :line)
:column (-> expr meta :column)
:end-line (-> expr meta :end-line)
:end-column (-> expr meta :end-column)
:alt simplified-expr})
(let [expr-meta (meta expr)]
{:expr expr
:line (:line expr-meta)
:column (:column expr-meta)
:end-line (:end-line expr-meta)
:end-column (:end-column expr-meta)
:alt simplified-expr}))

;; ### Guarding the check

Expand Down Expand Up @@ -164,23 +164,19 @@

;; The default resolution is overridden via the `merge`
(defn check-expr
""
[expr & kw-opts]
(let [{:keys [rules guard resolution]}
(merge default-args
{:resolution :toplevel}
(apply hash-map kw-opts))
rules (map unifier/prep rules)
simplify-fn #((res->simplify resolution) % rules)]
(check-aux expr simplify-fn guard)))

(defn check-reader
""
[reader & kw-opts]
(let [{:keys [rules guard resolution init-ns]}
(merge default-args
(apply hash-map kw-opts))
rules (map unifier/prep rules)
simplify-fn #((res->simplify resolution) % rules)]
(keep #(check-aux % simplify-fn guard)
((res->read-seq resolution) reader init-ns))))
Expand All @@ -190,7 +186,6 @@
{(resolve '*default-data-reader-fn*) (fn [tag val] val)}))

(defn check-file
""
[source-file & kw-opts]
(let [{:keys [rules guard resolution reporter init-ns]
:or {reporter reporters/cli-reporter}}
Expand Down
36 changes: 28 additions & 8 deletions src/kibit/check/reader.clj
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(ns kibit.check.reader
(:require [clojure.tools.reader :as reader])
(:require [edamame.core :as e])
(:import [clojure.lang LineNumberingPushbackReader]))

;; Preprocessing
Expand Down Expand Up @@ -69,8 +69,8 @@
(rest form))

(option-spec? form)
(let [[_ as? form-alias] form]
(deps-from-libspec prefix (first form) (when (= :as as?) form-alias)))
(let [opts (apply hash-map (next form))]
(deps-from-libspec prefix (first form) (or (:as opts) (:as-alias opts))))

(symbol? form)
(list (with-meta
Expand Down Expand Up @@ -142,18 +142,38 @@ into the namespace."

(def eof (Object.))

(defn- make-edamame-opts [alias-map]
(e/normalize-opts
{:all true
:read_eval true
:eof eof
:row-key :line
:col-key :column
:end-row-key :end-line
:end-col-key :end-column
:end-location true
:features #{:clj :cljs}
:read-cond :allow
:readers (fn reader [r]
(fn reader-value [v]
(list r v)))
:auto-resolve (fn [x]
(if (= :current x)
*ns*
(get alias-map x)))}))

(defn read-file
"Generate a lazy sequence of top level forms from a
LineNumberingPushbackReader"
[^LineNumberingPushbackReader r init-ns]
(let [ns (careful-refer (create-ns init-ns))
do-read (fn do-read [ns alias-map]
(lazy-seq
(let [form (binding [*ns* ns
reader/*alias-map* (merge (ns-aliases ns)
(alias-map ns))]
(reader/read {:eof eof :read-cond :preserve} r))
[ns? new-ns k] (when (sequential? form) form)
(let [form (binding [*ns* ns]
(e/parse-next r (make-edamame-opts
(merge (ns-aliases ns)
(alias-map ns)))))
[ns? new-ns] (when (sequential? form) form)
new-ns (unquote-if-quoted new-ns)
ns (if (and (symbol? new-ns)
(#{'ns 'in-ns} ns?))
Expand Down
2 changes: 1 addition & 1 deletion src/kibit/driver.clj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
(defn ends-with?
"Returns true if the java.io.File ends in any of the strings in coll"
[file coll]
(some #(.endsWith (.getName ^File file) %) coll))
(boolean (some #(.endsWith (.getName ^File file) %) coll)))

(defn clojure-file?
"Returns true if the java.io.File represents a Clojure source file.
Expand Down
5 changes: 1 addition & 4 deletions src/kibit/rules/arithmetic.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,4 @@
[(dec (Math/exp ?x)) (Math/expm1 ?x)]

;;ugly rounding tricks
[(long (+ ?x 0.5)) (Math/round ?x)]
)


[(long (+ ?x 0.5)) (Math/round ?x)])
21 changes: 0 additions & 21 deletions src/kibit/rules/control_structures.clj
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,3 @@
(while ?test . ?exprs)]
[(let ?binding (do . ?exprs)) (let ?binding . ?exprs)]
[(loop ?binding (do . ?exprs)) (loop ?binding . ?exprs)])

(comment
(when (not (pred? x y)) (f x y))

(if (all-streams-complete?)
(do
(deliver @all-clear :true)
(info "All streams complete.")))

(if (pred? x)
(do (action a)
(action b)
(if-let [x (f a b c)
y (g a b c)
z (h a b c)]
(do (+ 1 0)
(= 1 1)
(< 1 0)))
(action d)
(action f))
nil))
7 changes: 4 additions & 3 deletions src/kibit/rules/util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

(defmacro defrules [name & rules]
`(let [rules# (for [rule# '~rules]
(if (raw-rule? rule#)
(eval rule#) ;; raw rule, no need to compile
(compile-rule rule#)))]
(unifier/prep
(if (raw-rule? rule#)
(eval rule#) ;; raw rule, no need to compile
(compile-rule rule#))))]
(def ~name (vec rules#))))
3 changes: 2 additions & 1 deletion test/kibit/test/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"Hello" '(do "Hello")
'(when test then) '(do (when test then))
:one '(do :one)
{:one 1} '(do {:one 1})))
{:one 1} '(do {:one 1})
#{:a :b} '#{(do :a) (do :b)}))

;; This test confirms when checking will happen and when it won't
(deftest simplify-exprs
Expand Down
64 changes: 47 additions & 17 deletions test/kibit/test/driver.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,33 @@

(deftest clojure-file-are
(are [expected file] (= expected (driver/clojure-file? (io/file file)))
true "test/resources/first.clj"
true "test/resources/second.cljx"
true "test/resources/third.cljs"
false "test.resources/fourth.txt"))
true "corpus/first.clj"
true "corpus/second.cljx"
true "corpus/third.cljs"
false "corpus/fourth.txt"))

(deftest find-clojure-sources-are
(is (= [(io/file "test/resources/first.clj")
(io/file "test/resources/keyword_suggestions.clj")
(io/file "test/resources/keywords.clj")
(io/file "test/resources/reader_conditionals.cljc")
(io/file "test/resources/second.cljx")
(io/file "test/resources/sets.clj")
(io/file "test/resources/third.cljs")]
(driver/find-clojure-sources-in-dir (io/file "test/resources")))))
(is (= [(io/file "corpus/as_alias.clj")
(io/file "corpus/double_pound_reader_macros.clj")
(io/file "corpus/first.clj")
(io/file "corpus/keyword_suggestions.clj")
(io/file "corpus/keywords.clj")
(io/file "corpus/namespaced_maps.clj")
(io/file "corpus/read_eval.clj")
(io/file "corpus/reader_conditionals.cljc")
(io/file "corpus/second.cljx")
(io/file "corpus/sets.clj")
(io/file "corpus/third.cljs")]
(driver/find-clojure-sources-in-dir (io/file "corpus")))))

(deftest test-set-file
(is (driver/run ["test/resources/sets.clj"] nil)))
(is (driver/run ["corpus/sets.clj"] nil)))

(deftest test-keywords-file
(let [test-buf (ByteArrayOutputStream.)
test-err (PrintWriter. test-buf)]
(binding [*err* test-err]
(driver/run ["test/resources/keywords.clj"] nil))
(driver/run ["corpus/keywords.clj"] nil))
(is (zero? (.size test-buf))
(format "Test err buffer contained '%s'" (.toString test-buf)))))

Expand All @@ -42,7 +46,33 @@
{:alt (vec [:clojure.pprint/printing-key :resources.keyword-suggestions/local-key4 :some/other-key4])
:expr (into [] [:clojure.pprint/printing-key :resources.keyword-suggestions/local-key4 :some/other-key4])})
(map #(select-keys % [:expr :alt])
(driver/run ["test/resources/keyword_suggestions.clj"] nil "--reporter" "no-op")))))
(driver/run ["corpus/keyword_suggestions.clj"] nil "--reporter" "no-op")))))

(deftest process-cljc-file
(is (driver/run ["test/resources/reader_conditionals.cljc"] nil)))
(defmacro with-err-str
[& body]
`(let [s# (java.io.StringWriter.)]
(binding [*err* s#]
~@body
(str s#))))

(deftest process-reader-macros
(is (= ["" "" "" ""]
[(with-err-str
(driver/run ["corpus/reader_conditionals.cljc"] nil "--reporter" "no-op"))
(with-err-str
(driver/run ["corpus/double_pound_reader_macros.clj"] nil "--reporter" "no-op"))
(with-err-str
(driver/run ["corpus/namespaced_maps.clj"] nil "--reporter" "no-op"))
(with-err-str
(driver/run ["corpus/as_alias.clj"] nil "--reporter" "no-op"))])))

(deftest no-read-eval-test
(is (= [{:expr
'(if true (do (edamame.core/read-eval (prn :hello :world!)) :a))
:line 1
:column 1
:end-line 1
:end-column 41
:alt '(when true (edamame.core/read-eval (prn :hello :world!)) :a)}]
(map #(dissoc % :file)
(driver/run ["corpus/read_eval.clj"] nil "--reporter" "no-op")))))

0 comments on commit a7f77b0

Please sign in to comment.