Back
requiring-resolve (clj)
(source)function
(requiring-resolve sym)
Resolves namespace-qualified sym per 'resolve'. If initial resolve
fails, attempts to require sym's namespace and retries.
Examples
typedclojure/typedclojure
In general these operations:
- are macros instead of functions
- take Typed Clojure types instead of malli schemas
- helps the type checker infer their results
See also:
- typed.malli.generator
- typed.malli.swagger
- typed.malli.json-schema"
(:require [typed.clojure :as t]
[clojure.core.typed.unsafe :as unsafe]
[malli.core :as m]))
(defmacro validate
"Validate v as type t. Type checker infers as a predicate
on t.
eg.,
(validate t/AnyInteger 1) => true
(validate t/AnyInteger nil) => false"
[t v]
`((unsafe/ignore-with-unchecked-cast
m/validate
[t/Any t/Any :-> t/Bool :filters {:then (~'is ~t 1)
:else (~'! ~t 1)}])
~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)
~v))
(defmacro validator
"Create validator for type t. Type checker infers as a predicate
on t.
eg.,
((validator t/AnyInteger) 1) => true
((validator t/AnyInteger) nil) => false"
[t]
`((unsafe/ignore-with-unchecked-cast
m/validator
[t/Any :-> [t/Any :-> t/Bool :filters {:then (~'is ~t 0)
:else (~'! ~t 0)}]])
~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)))
(defmacro explain
"Explain validation failure of v conforming to type t. Type checker infers as a predicate
on \"not t\".
(explain t/AnyInteger 1) => nil
(explain t/AnyInteger nil)
=>
{:schema :int,
:value nil,
:errors
({:path [],
:in [],
:schema :int,
:value nil,
:type nil,
:message nil})}"
[t v]
`((unsafe/ignore-with-unchecked-cast
m/explain
[t/Any t/Any :-> (t/Nilable '{:schema t/Any
:value t/Any
:errors (t/Seqable t/Any)})
:filters {:then (~'! ~t 1)
:else (~'is ~t 1)}])
~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)
~v))
(defmacro parse
"Parse value v as type t. Type checker infers the shape of
return value.
eg.,
(parse t/AnyInteger 1) ;=> 1
(parse t/AnyInteger nil) ;=> :malli.core/invalid
(parse (t/U ^{::name :int} t/AnyInteger
^{::name :bool} t/Bool)
1)
;=> [:int 1]
(parse (t/U ^{::name :int} t/AnyInteger
^{::name :bool} t/Bool)
true)
;=> [:bool true]"
[t v]
`((unsafe/ignore-with-unchecked-cast
m/parse
[t/Any t/Any :-> (t/U '::m/invalid ~(-> t
((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax))
((requiring-resolve 'typed.malli.schema-to-type/malli-syntax->parser-type))))])
~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)
~v))
(defmacro parser
"Create parser for Typed Clojure type t. Type checker infers
the type of the return value when used.
eg.,
((parser t/AnyInteger) 1) ;=> 1
((parser t/AnyInteger) nil) ;=> :malli.core/invalid
((parser (t/U ^{::name :int} t/AnyInteger
^{::name :bool} t/Bool))
1)
;=> [:int 1]
((parser (t/U ^{::name :int} t/AnyInteger
^{::name :bool} t/Bool))
true)
;=> [:bool true]"
[t]
`(m/parser ~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)))
(defmacro defparser
"Def parser for Typed Clojure type t. Type checker infers
the type of the return value when used.
eg.,
(defparser AnyInteger-parser t/AnyInteger)
(AnyInteger-parser 1) ;=> 1
(AnyInteger-parser nil) ;=> :malli.core/invalid"
[name t]
`(do (t/ann ~(vary-meta name assoc :no-check true)
[t/Any :-> (t/U (t/Val ::m/invalid)
~(-> t
((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax))
((requiring-resolve 'typed.malli.schema-to-type/malli-syntax->parser-type))))])
(def ~name (parser ~t))))
(defmacro unparse [t v]
`(m/unparse ~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)
~v))
(defmacro unparser [t]
`(m/unparser ~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)))
(defmacro -instrument [tmap & args]
`(m/-instrument ~(update tmap :schema (requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax))
~@args))
(defmacro => [name t]
`(m/=> ~name ~((requiring-resolve 'typed.malli.parse-type/type-syntax->malli-syntax) t)))
typedclojure/typedclojure
(ns typed.clojure.jvm
"JVM-specific annotations and operations.
See typed.clojure for cross-platform ops."
(:require clojure.core.typed
[clojure.core.typed.current-impl :as impl]
[clojure.core.typed.internal :refer [take-when]]
[typed.cljc.runtime.env-utils :refer [delay-type]]
[clojure.core.typed.macros :as macros]))
(defmacro override-class [& args]
(let [[binder args] (take-when vector? args)
[nme args] (take-when symbol? args)
_ (assert (symbol? nme) (str "Missing name in override-class" [nme args]))
[opts args] (take-when map? args)
opts (if opts
(do (assert (empty? args) (str "Trailing args to override-class: " (pr-str args)))
opts)
(apply hash-map args))
this-ns (ns-name *ns*)]
`(clojure.core.typed/tc-ignore
(let [nme# (or (when-some [^Class c# (ns-resolve '~this-ns '~nme)]
(when (class? c#)
(-> c# .getName symbol)))
(throw (ex-info (str "Could not resolve class: " '~nme) {:class-name '~nme})))]
;; TODO runtime env
#_
(impl/add-rclass-env nme# {:op :RClass})
;; type env
;inline when-bindable-defining-ns
(macros/when-bindable-defining-ns '~this-ns
(impl/with-clojure-impl
(impl/add-rclass nme# (delay-type
((requiring-resolve 'typed.clj.checker.parse-unparse/with-parse-ns*)
'~this-ns
#((requiring-resolve 'typed.cljc.checker.base-env-helper/make-RClass)
nme#
'~binder
'~opts))))))))))
typedclojure/typedclojure
(ns ^:no-doc typed.cljc.checker.check-impl
(:require [clojure.core.typed.current-impl :as impl]
[typed.cljc.analyzer :as ana2]
[typed.cljc.checker.check.binding :as binding]
[typed.cljc.checker.check.catch :as catch]
[typed.cljc.checker.check.const :as const]
[typed.cljc.checker.check.do :as do]
[typed.cljc.checker.check.fn :as fn]
[typed.cljc.checker.check.if :as if]
[typed.cljc.checker.check.invoke :as invoke]
[typed.cljc.checker.check.let :as let]
[typed.cljc.checker.check.letfn :as letfn]
[typed.cljc.checker.check.local :as local]
[typed.cljc.checker.check.loop :as loop]
[typed.cljc.checker.check.map :as map]
[typed.cljc.checker.check.quote :as quote]
[typed.cljc.checker.check.recur :as recur]
[typed.cljc.checker.check.set :as set]
[typed.cljc.checker.check.set-bang :as set!]
[typed.cljc.checker.check.throw :as throw]
[typed.cljc.checker.check.try :as try]
[typed.cljc.checker.check.vector :as vec]
[typed.cljc.checker.check.with-meta :as with-meta]))
(defmethod -check ::ana2/var
[expr expected]
((impl/impl-case
:clojure (requiring-resolve 'typed.clj.checker.check/check-var)
:cljs (requiring-resolve 'typed.cljs.checker.check/check-var))
expr expected))
(defmethod -check ::ana2/the-var
[expr expected]
((impl/impl-case
:clojure (requiring-resolve 'typed.clj.checker.check/check-the-var)
:cljs (requiring-resolve 'typed.cljs.checker.check/check-the-var))
expr expected))
(defmethod -check ::ana2/def
[expr expected]
((impl/impl-case
:clojure (requiring-resolve 'typed.clj.checker.check/check-def)
:cljs (requiring-resolve 'typed.cljs.checker.check/check-def))
expr expected))
(defmethod -check ::ana2/new
[expr expected]
((impl/impl-case
:clojure (requiring-resolve 'typed.clj.checker.check/check-new)
:cljs (requiring-resolve 'typed.cljs.checker.check/check-new))
expr expected))
typedclojure/typedclojure
(ns ^:no-doc typed.ann.clojure
"Type annotations for the base Clojure distribution."
#?(:cljs (:require-macros [typed.ann-macros.clojure :as macros]))
(:require [clojure.core :as cc]
[typed.clojure :as t]
#?(:clj [typed.ann-macros.clojure :as macros])
#?(:clj typed.ann.clojure.jvm) ;; jvm annotations
#?(:clj clojure.core.typed))
#?(:clj
(:import (clojure.lang PersistentHashSet PersistentList
APersistentMap #_IPersistentCollection
#_ITransientSet
IRef)
(java.util Comparator Collection))))
#?@(:cljs [] :default [
cc/require [t/Any :* :-> nil]
cc/requiring-resolve [t/Sym :-> (t/Nilable t/AnyVar)]
cc/use [t/Any :* :-> nil]
cc/*loaded-libs* (t/Ref (t/Set t/Sym))
])
typedclojure/typedclojure
(ns typed-test.malli
(:require [clojure.test :refer [deftest is]]
[clojure.core.typed :as t]
[typed.malli :as sut] ;:as tm
[typed.clj.checker.test-utils :refer [is-tc-e is-tc-err]]
[malli.core :as m]))
(comment
(m/parse Hiccup [:div [:p "foo"]])
(m/parse Hiccup [:div [:p :a "foo"]])
((requiring-resolve 'clojure.repl/pst) 100)
)