Skip to content

Commit fad8ae9

Browse files
committed
add infer/instrument-top-level-form
1 parent 3d70885 commit fad8ae9

File tree

3 files changed

+66
-41
lines changed

3 files changed

+66
-41
lines changed

deps.edn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{:paths ["src/main/clojure"
22
"src/main/cljc"]
33
:deps {org.clojure/core.typed.runtime.jvm {:mvn/version "0.7.1-SNAPSHOT"}
4-
org.clojure/core.typed.checker.jvm {:mvn/version "0.7.1-SNAPSHOT"}
4+
org.clojure/core.typed.analyzer.jvm {:mvn/version "0.7.1"}
55
org.clojure/tools.reader {:mvn/version "1.1.1"}
66
org.clojure/tools.namespace {:mvn/version "0.3.0-alpha4"}
77
org.clojure/math.combinatorics {:mvn/version "0.1.4"

src/main/cljc/clojure/core/typed/runtime_infer.cljc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@
129129
[clojure.java.io :as io]
130130
[clojure.core.typed.ast-utils :as ast]
131131
[clojure.tools.analyzer.passes.jvm.emit-form :as emit-form]
132+
[clojure.core.typed.analyzer.jvm :as jana2]
133+
[clojure.tools.analyzer.jvm :as taj]
132134
[clojure.core.typed.annotator.insert :as insert
133135
:refer [replace-generated-annotations]]
134136
[clojure.core.typed.coerce-utils :as coerce]])))
@@ -2895,6 +2897,16 @@
28952897
;(defn instrument-ns [v]
28962898
; )
28972899

2900+
#?(:clj
2901+
(defn instrument-top-level-form
2902+
[form]
2903+
(impl/with-clojure-impl
2904+
(jana2/analyze+eval form (taj/empty-env) {:eval-fn (fn [ast opts]
2905+
(-> ast
2906+
runtime-infer-expr
2907+
(jana2/eval-ast opts)))})))
2908+
)
2909+
28982910
;; TESTS
28992911

29002912
(comment

src/test/clojure/clojure/core/typed/annotator/test/runtime_infer.clj

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@
88
[com.gfredericks.test.chuck.generators :as gen']
99
[clojure.test.check.generators :as gen]
1010
[clojure.core.typed :as t]
11+
[clojure.core.typed.analyzer :as ana2]
12+
[clojure.tools.analyzer.jvm :as taj]
13+
[clojure.core.typed.analyzer.jvm :as jana2]
1114
[clojure.core.typed.runtime-infer :refer :all :as infer]
12-
[clojure.core.typed.checker.jvm.check-form-clj :as chk-clj]
1315
[clojure.core.typed.coerce-utils :as coerce]
1416
[clojure.core.typed.annotator.pprint :refer [pprint]]
1517
[clojure.core.typed.annotator.parse :refer [prs parse-type]]
1618
[clojure.core.typed.annotator.rep :refer [infer-result
1719
var-path
1820
key-path
1921
fn-rng-path
20-
fn-dom-path ]]
22+
fn-dom-path]]
2123
[clojure.core.typed.annotator.track :refer [track-var]]
2224
[clojure.core.typed.annotator.join :refer [make-Union
2325
join*
@@ -1066,60 +1068,51 @@
10661068
{'config-in t}
10671069
))))
10681070

1069-
(defmacro infer-test
1070-
"Given a vector of definitions :defs and a vector of tests :tests, then
1071-
does these steps in order. Short-circuits and returns a false value if previous steps fail.
1072-
Returns a true value on success.
1071+
(deftest instrument-top-level-form-test
1072+
(is (.contains (with-out-str (instrument-top-level-form '(println "a")))
1073+
"a\n"))
1074+
(is (.contains
1075+
(with-out-str (instrument-top-level-form '(do (def a "a") (println a))))
1076+
"a\n")))
10731077

1074-
1. Generates specs and types for the definitions
1075-
2. Ensure generated specs and types are identical to :expected-types and :expected-specs, respectively (when provided).
1076-
These are either vectors of annotations, or a string that contains vectors
1077-
of annotations that will be `read` in the correct namespace (useful to aid keyword namespace
1078-
resolution in specs).
1079-
If one of these is not provided, the respective annotations are pprint'ed so they can
1080-
be easily copied into the test.
1081-
3. Evaluates generated specs.
1082-
4. Exercises spec aliases.
1083-
5. Exercises spec'd functions.
1084-
6. Instruments all spec'd functions.
1085-
7. Runs :test code again under spec instrumentation."
1086-
[& {:keys [defs tests expected-specs expected-types] :as opts}]
1078+
(declare *-from-infer-results)
1079+
1080+
;TODO remove # suffixes
1081+
(defn infer-test*
1082+
[{:keys [defs tests expected-specs expected-types] :as opts}]
10871083
(assert (vector? defs))
10881084
(assert (vector? tests))
1089-
`(let [ns# (create-ns (gensym))]
1085+
(let [ns# (create-ns (gensym))]
10901086
(binding [*ns* ns#
10911087
*ann-for-ns* (constantly ns#)]
10921088
(refer-clojure)
1093-
(require '~'[clojure.core.typed :as t])
1089+
(require '[clojure.core.typed :as t])
10941090
(when spec-ns
1095-
(require [spec-ns :as '~'s]))
1091+
(require [spec-ns :as 's]))
10961092
(let [result# (atom :ok)
10971093
run-until-bad-result!# (fn [f# c#]
10981094
(loop [c# c#]
10991095
(when @result#
11001096
(when (seq c#)
11011097
(do (f# (first c#))
11021098
(recur (rest c#)))))))
1103-
defs# '~defs
1104-
tests# '~tests
1105-
_# (t/refresh-runtime-infer)
1099+
defs# defs
1100+
tests# tests
1101+
_# (infer/refresh-runtime-infer)
11061102
_# (run-until-bad-result!#
11071103
(fn [f#]
1108-
(let [{ex# :ex} (chk-clj/check-form-info-with-config
1109-
f#
1110-
(assoc (chk-clj/config-map) :should-runtime-infer? true)
1111-
{})]
1112-
(when ex#
1113-
(println (str "Form " f# " failed to evaluate, with error: " ex#))
1114-
(reset! result# nil))))
1104+
(try (instrument-top-level-form f#)
1105+
(catch Throwable e#
1106+
(println (str "Failed to evaluate " f# " with error " e#))
1107+
(reset! result# nil))))
11151108
(concat defs# tests#))]
11161109
(when @result#
1117-
(let [expected-specs# (let [s# '~expected-specs]
1110+
(let [expected-specs# (let [s# expected-specs]
11181111
(if (string? s#)
11191112
(read-string s#)
11201113
s#))
11211114
_# (assert ((some-fn nil? vector?) expected-specs#))
1122-
expected-types# (let [t# '~expected-types]
1115+
expected-types# (let [t# expected-types]
11231116
(if (string? t#)
11241117
(read-string t#)
11251118
t#))
@@ -1149,26 +1142,26 @@
11491142
(let [instrumentable-syms# (set
11501143
(keep (fn [spc#]
11511144
(when (seq? spc#)
1152-
(when (= '~'s/fdef (first spc#))
1145+
(when (= 's/fdef (first spc#))
11531146
(let [^clojure.lang.Var v# (resolve (second spc#))]
11541147
(when (var? v#)
11551148
(coerce/var->symbol v#))))))
11561149
(:top-level specs#)))
11571150
spec-defs# (set
11581151
(keep (fn [spc#]
11591152
(when (seq? spc#)
1160-
(when (= '~'s/def (first spc#))
1153+
(when (= 's/def (first spc#))
11611154
(let [kw# (second spc#)]
11621155
(when (keyword? kw#)
11631156
(when (namespace kw#)
11641157
kw#))))))
11651158
(:top-level specs#)))
1166-
_# (require ['~'clojure.spec.test.alpha])
1167-
instrument# (resolve '~'clojure.spec.test.alpha/instrument)
1159+
_# (require ['clojure.spec.test.alpha])
1160+
instrument# (resolve 'clojure.spec.test.alpha/instrument)
11681161
_# (assert instrument#)
1169-
exercise# (resolve '~'clojure.spec.alpha/exercise)
1162+
exercise# (resolve 'clojure.spec.alpha/exercise)
11701163
_# (assert exercise#)
1171-
exercise-fn# (resolve '~'clojure.spec.alpha/exercise-fn)
1164+
exercise-fn# (resolve 'clojure.spec.alpha/exercise-fn)
11721165
_# (assert exercise-fn#)
11731166
exercise-fn-or-fail# (fn [sym#]
11741167
(try (doall (exercise-fn# sym#))
@@ -1219,6 +1212,26 @@
12191212
(run-until-bad-result!# eval-or-fail# tests#))))
12201213
@result#))))))
12211214

1215+
(defmacro infer-test
1216+
"Given a vector of definitions :defs and a vector of tests :tests, then
1217+
does these steps in order. Short-circuits and returns a false value if previous steps fail.
1218+
Returns a true value on success.
1219+
1220+
1. Generates specs and types for the definitions
1221+
2. Ensure generated specs and types are identical to :expected-types and :expected-specs, respectively (when provided).
1222+
These are either vectors of annotations, or a string that contains vectors
1223+
of annotations that will be `read` in the correct namespace (useful to aid keyword namespace
1224+
resolution in specs).
1225+
If one of these is not provided, the respective annotations are pprint'ed so they can
1226+
be easily copied into the test.
1227+
3. Evaluates generated specs.
1228+
4. Exercises spec aliases.
1229+
5. Exercises spec'd functions.
1230+
6. Instruments all spec'd functions.
1231+
7. Runs :test code again under spec instrumentation."
1232+
[& {:keys [defs tests expected-specs expected-types] :as opts}]
1233+
`(infer-test* '~opts))
1234+
12221235
(defn *-from-infer-results [ns config]
12231236
(binding [*ann-for-ns* (constantly *ns*)
12241237
*debug* (if-let [[_ debug] (find config :debug)]

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy