From b50ff992b1cca01838a0de93db845b7b3d933d01 Mon Sep 17 00:00:00 2001 From: Noah Bogart Date: Tue, 8 Aug 2023 16:32:24 -0400 Subject: [PATCH 1/2] Add Actions build and deps.edn --- .github/workflows/build.yml | 26 +++++++++++++++++++++++++ deps.edn | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 deps.edn diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..2fa83e6c72 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,26 @@ +name: Java CI + +on: [push] + +jobs: + build: + timeout-minutes: 5 + strategy: + matrix: + jdk: ['8', '11', '17', '19'] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK ${{ matrix.jdk }} + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.jdk }} + distribution: 'temurin' + cache: maven + - name: Build with Maven + run: mvn test + - name: Configure settings.xml + run: | + mkdir -p ~/.m2 + echo "clojars${{ secrets.CLOJARS_USER }}-clojars${{ secrets.CLOJARS_PASSWORD }}" > ~/.m2/settings.xml diff --git a/deps.edn b/deps.edn new file mode 100644 index 0000000000..1b5a7ea601 --- /dev/null +++ b/deps.edn @@ -0,0 +1,38 @@ +;; https://clojure.org/dev/developing_patches#_run_an_individual_test +{:paths ["test" + "target/test-classes"] + :deps + {org.clojure/clojure {:local/root "." + :deps/manifest :pom} #_{:mvn/version "RELEASE"} + org.clojure/test.check {:mvn/version "1.1.1"} + org.clojure/test.generative {:mvn/version "1.0.0"}} + :aliases + {:dbg {:classpath-overrides {org.clojure/clojure "target/classes"} + :extra-deps {criterium/criterium {:mvn/version "0.4.4"}}} + :cognitest {:extra-deps {io.github.cognitect-labs/test-runner + {:git/tag "v0.5.0" :git/sha "b3fd0d2"}} + :main-opts ["-m" "cognitect.test-runner"] + :exec-fn cognitect.test-runner.api/test + :exec-args {:dirs ["test"] + :patterns [;; FIXME clojure.test-clojure.ns-libs has a test that is sensitive to loading order + ;; FIXME clojure.test-clojure.java-interop doesn't seem to work on JDK 17 (untested on others) + ;; regex ref: https://stackoverflow.com/a/2387072 + "^((?!(clojure.test-clojure.ns-libs|clojure.test-clojure.java-interop)).)*$" + ]}} + :test-example-script {:jvm-opts [;; from build.xml + "-Dclojure.test-clojure.exclude-namespaces=#{clojure.test-clojure.compilation.load-ns clojure.test-clojure.ns-libs-load-later}" + "-Dclojure.compiler.direct-linking=true"] + :main-opts ["-e" "(load-file,\"src/script/run_test.clj\")"]} + :test-generative-script {:jvm-opts [;; from build.xml + "-Dclojure.compiler.direct-linking=true"] + :main-opts ["-e" "(load-file,\"src/script/run_test_generative.clj\")"]} + + :kaocha {:extra-deps {lambdaisland/kaocha {:mvn/version "1.60.977"}} + :exec-fn kaocha.runner/exec-fn + :exec-args {;:watch? true + :tests [{:id :unit + :test-paths ["test"] + :ns-patterns [".*"]}] + :reporter kaocha.report/dots + ;; :plugins [:kaocha.plugin/profiling :kaocha.plugin/notifier] + }}}} From 73b02bce783f5a63cbbbedbdd26560e5a7a22d31 Mon Sep 17 00:00:00 2001 From: Noah Bogart Date: Tue, 8 Aug 2023 17:10:29 -0400 Subject: [PATCH 2/2] CLJ-2094 - Eagerly evaluated protocols should refer to latest versions By referencing the `:var` on protocols when passed to protocol functions, any protocols that are eagerly evaluated (in functions such as `partial`) will properly use the most up-to-date set of `:impls` on the protocol instead of those that exist at partial-application time. --- src/clj/clojure/core_deftype.clj | 10 +++++++-- test/clojure/test_clojure/protocols.clj | 27 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/clj/clojure/core_deftype.clj b/src/clj/clojure/core_deftype.clj index c2babab291..a63232d42f 100644 --- a/src/clj/clojure/core_deftype.clj +++ b/src/clj/clojure/core_deftype.clj @@ -533,10 +533,16 @@ ([^Class a ^Class b] (if (.isAssignableFrom a b) b a))) +(defn- latest-p + "Get the latest version of the protocol before use." + [protocol] + (deref (:var protocol))) + (defn find-protocol-impl [protocol x] (if (instance? (:on-interface protocol) x) x (let [c (class x) + protocol (latest-p protocol) impl #(get (:impls protocol) %)] (or (impl c) (and c (or (first (remove nil? (map impl (butlast (super-chain c))))) @@ -559,13 +565,13 @@ {:added "1.2"} [protocol atype] (boolean (or (implements? protocol atype) - (get (:impls protocol) atype)))) + (get (:impls (latest-p protocol)) atype)))) (defn extenders "Returns a collection of the types explicitly extending protocol" {:added "1.2"} [protocol] - (keys (:impls protocol))) + (keys (:impls (latest-p protocol)))) (defn satisfies? "Returns true if x satisfies the protocol" diff --git a/test/clojure/test_clojure/protocols.clj b/test/clojure/test_clojure/protocols.clj index 4e951449bb..2388bf0a9f 100644 --- a/test/clojure/test_clojure/protocols.clj +++ b/test/clojure/test_clojure/protocols.clj @@ -691,6 +691,33 @@ (reify LongsHintedProto (longs-hinted [_] (long-array [1]))))))) +;; CLJ-2094 - Eagerly evaluated protocols should refer to latest versions + +(require '[clojure.spec.alpha :as s]) + +(defprotocol CLJ-2094 + (execute [_])) + +(def partial-extends-clj-2094 (partial extends? CLJ-2094)) +(def partial-extenders-clj-2094 (partial extenders CLJ-2094)) +(def partial-find-protocol-method-clj-204 + (partial find-protocol-method CLJ-2094 :execute)) +(def partial-satisfies-clj-2094 (partial satisfies? CLJ-2094)) +(s/def ::clj-2094 (partial satisfies? CLJ-2094)) + +(defrecord Foo-2094 []) + +(extend-type Foo-2094 + CLJ-2094 + (execute [_])) + +(deftest test-satisfies-uses-latest + (is (partial-extends-clj-2094 Foo-2094)) + (is (= [Foo-2094] (partial-extenders-clj-2094))) + (is (partial-find-protocol-method-clj-204 (->Foo-2094))) + (is (partial-satisfies-clj-2094 (->Foo-2094))) + (is (s/valid? ::clj-2094 (->Foo-2094)))) + ;; CLJ-1180 - resolve type hints in protocol methods (import 'clojure.lang.ISeq)