From 7ee2a62fdaea0f2e4db540915ecc25b6773c5c93 Mon Sep 17 00:00:00 2001 From: lread Date: Sat, 2 Sep 2023 10:09:56 -0400 Subject: [PATCH] Support analysis of Clojure 1.9+ A signature change in JDK11 means gvec.clj needs a type hint See https://clojure.atlassian.net/browse/CLJ-2374 This change patches gvec.clj with the necessary type hint. An alternative would be to run analysis under JDK8, but cljdoc does not currently support JDK selection at this time. Contributes to #53 --- CHANGELOG.adoc | 2 +- src/cljdoc_analyzer/runner.clj | 31 ++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index b1065a8..ca236ba 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -10,7 +10,7 @@ == Unreleased -* Support analysis of clojure itself (v1.10.0+) +* Support analysis of clojure itself (v1.9+) https://github.com/cljdoc/cljdoc-analyzer/issues/53[#53] * Internal :namespaces option now applied before analysis https://github.com/cljdoc/cljdoc-analyzer/issues/92[#92] diff --git a/src/cljdoc_analyzer/runner.clj b/src/cljdoc_analyzer/runner.clj index d51e5e3..b9decad 100644 --- a/src/cljdoc_analyzer/runner.clj +++ b/src/cljdoc_analyzer/runner.clj @@ -21,7 +21,8 @@ [cljdoc-analyzer.file :as file] [cljdoc-shared.proj :as proj] [cljdoc-shared.spec.analyzer :as analyzer-spec] - [cljdoc-shared.analysis-edn :as analysis-edn]) + [cljdoc-shared.analysis-edn :as analysis-edn] + [version-clj.core :as v]) (:import (java.net URI) (org.objectweb.asm ClassReader ClassVisitor Opcodes))) @@ -105,6 +106,29 @@ (log/info "Deleting" path) (fs/delete file)))) +(defn- patch-jar-contents! + "Sometimes an old project version will need a tweak to analyze. + For now we handle these tweaks here. + Please use this judiciously and provide comments as to why the tweak is necessary." + [project version unpacked-jar-dir] + ;; Patch gvec.clj in clojure <= 1.9.0 + ;; + ;; A signature change in JDK11 means gvec.clj needs a type hint + ;; See https://clojure.atlassian.net/browse/CLJ-2374 + ;; This patch applies the necessary type hint. + ;; An alternative would be to run analysis under JDK8, but cljdoc does not + ;; currently support JDK selection at this time. + (let [gvec-file (fs/file unpacked-jar-dir "clojure/gvec.clj")] + (when (and (= 'org.clojure/clojure project) + (v/older-or-equal? version "1.9.0") + (fs/exists? gvec-file)) + (log/infof "Patching gvec.clj signature in org.clojure/cloure version %s" version) + (let [in (slurp gvec-file) + out (string/replace in + "(toArray [this arr]" + "(^objects toArray [this ^objects arr]")] + (spit gvec-file out))))) + (defn- resolve-jar! "Returns local path to `jar`, if download necessary, downloads to `target-dir`" [jar target-dir] @@ -117,12 +141,13 @@ "Returns dir where jar contents has been unpacked under `target-dir`. dir will be relative to target-dir in a way suitable for use with a pom.xml as a local root." - [local-jar-path target-dir] + [project version local-jar-path target-dir] ;; If a pom is read from target-dir, src/main/clojure relative to that pom is ;; added to the classpath by tdeps. (let [jar-contents-dir (io/file target-dir "src/main/clojure")] (fs/unzip local-jar-path jar-contents-dir) (clean-jar-contents! jar-contents-dir) + (patch-jar-contents! project version jar-contents-dir) jar-contents-dir)) (defn- log-process-result [proc] @@ -199,7 +224,7 @@ (try (let [project (symbol project) local-jar-path (resolve-jar! jarpath work-dir) - jar-contents-dir (unpack-jar! local-jar-path work-dir) + jar-contents-dir (unpack-jar! project version local-jar-path work-dir) pom-str (slurp pompath) ;; Utilize unpack-jar!'s deps.edn support, and create a path which ;; tdeps can understand.