Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 27 additions & 19 deletions src/sci/impl/analyzer.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1464,17 +1464,17 @@
(defn analyze-call [ctx expr m top-level?]
(with-top-level-loc top-level? m
(try
(let [f (first expr)]
(cond (symbol? f)
(let [fsym f
(let [f* (first expr)]
(cond (symbol? f*)
(let [fsym f*
;; in call position Clojure prioritizes special symbols over
;; bindings
special-sym (get special-syms f)
special-sym (get special-syms f*)
_ (when (and special-sym
(:check-permissions ctx))
(resolve/check-permission! ctx f [special-sym nil]))
(resolve/check-permission! ctx f* [special-sym nil]))
f (or special-sym
(resolve/resolve-symbol ctx f true))
(resolve/resolve-symbol ctx f* true))
f-meta (meta f)
eval? (and f-meta (:sci.impl/op f-meta))
fast-path (-> f-meta :sci.impl/fast-path)
Expand Down Expand Up @@ -1555,15 +1555,23 @@
:sci.impl/f-meta f-meta)
^"[Ljava.lang.Class;" arg-types (when (pos? arg-count)
(make-array Class arg-count))
has-types? (volatile! nil)]
has-types? (volatile! nil)
]
(when arg-types
(areduce args idx _ret nil
(let [arg (aget args idx)
arg-meta (meta arg)]
(when-let [t (:tag arg-meta)]
(when-let [t (interop/resolve-type-hint ctx t)]
(do (vreset! has-types? true)
(aset arg-types idx t)))))))
(or (when-let [param-tags (-> f* (some-> meta :param-tags))]
(vreset! has-types? true)
(areduce arg-types idx _ret nil
(when-let [t (nth param-tags idx)]
(when-not (= '_ t)
(when-let [t (interop/resolve-type-hint ctx t)]
(aset arg-types idx t))))))
(areduce args idx _ret nil
(let [arg (aget args idx)
arg-meta (meta arg)]
(when-let [t (:tag arg-meta)]
(when-let [t (interop/resolve-type-hint ctx t)]
(do (vreset! has-types? true)
(aset arg-types idx t))))))))
(sci.impl.types/->Node
(let [obj (sci.impl.types/eval obj ctx bindings)]
(interop/invoke-instance-method ctx bindings obj clazz
Expand Down Expand Up @@ -1656,23 +1664,23 @@
:file @utils/current-file
:sci.impl/f-meta f-meta)]
(sci.impl.types/->Node nil stack)))))))
(keyword? f)
(keyword? f*)
(let [children (analyze-children ctx (rest expr))
ccount (count children)]
(case ccount
1 (let [arg (nth children 0)]
(sci.impl.types/->Node
(f (t/eval arg ctx bindings))
(f* (t/eval arg ctx bindings))
nil))
2 (let [arg0 (nth children 0)
arg1 (nth children 1)]
(sci.impl.types/->Node
(f (t/eval arg0 ctx bindings)
(f* (t/eval arg0 ctx bindings)
(t/eval arg1 ctx bindings))
nil))
(throw-error-with-location (str "Wrong number of args (" ccount ") passed to: " f) expr)))
(throw-error-with-location (str "Wrong number of args (" ccount ") passed to: " f*) expr)))
:else
(let [f (analyze ctx f)
(let [f (analyze ctx f*)
children (analyze-children ctx (rest expr))
stack (assoc m
:ns @utils/current-ns
Expand Down
11 changes: 6 additions & 5 deletions test/sci/interop_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -374,11 +374,12 @@
(testing "type hinting on fn expression as argument with Callable returns nil on futuretask get"
(is (= 3 (sci/eval-string "(def fut (.submit (java.util.concurrent.Executors/newCachedThreadPool) ^java.util.concurrent.Callable (fn [] 3))) (.get fut)" type-hint-config))))
(testing "similar cases but with qualified interop"
(is (nil? (sci/eval-string "(def ^java.util.concurrent.ExecutorService thread-pool (java.util.concurrent.Executors/newCachedThreadPool))
@(java.util.concurrent.ExecutorService/.submit thread-pool ^Runnable (fn [] 3))"
type-hint-config)))
(is (= 3 (sci/eval-string "(def ^java.util.concurrent.ExecutorService thread-pool (java.util.concurrent.Executors/newCachedThreadPool))
@(java.util.concurrent.ExecutorService/.submit thread-pool ^Callable (fn [] 3))"
(is (= [nil nil 3 3] (sci/eval-string "(def ^java.util.concurrent.ExecutorService thread-pool (java.util.concurrent.Executors/newCachedThreadPool))
[
@(java.util.concurrent.ExecutorService/.submit thread-pool ^Runnable (fn [] 3))
@(^[Runnable] java.util.concurrent.ExecutorService/.submit thread-pool (fn [] 3))
@(java.util.concurrent.ExecutorService/.submit thread-pool ^Callable (fn [] 3))
@(^[Callable ]java.util.concurrent.ExecutorService/.submit thread-pool (fn [] 3))]"
type-hint-config)))))
(testing "type hint on interop argument"
;; this test assumes clojure/core.clj comes from a jar file
Expand Down
Loading