Skip to content

Commit 606669f

Browse files
authored
Partial fix for #963 (#994)
* add failing test * Partial fix for #963
1 parent 7563760 commit 606669f

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

src/sci/impl/analyzer.cljc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,22 +1542,33 @@
15421542
(interop/invoke-static-method ctx bindings class method children))
15431543
nil)))))
15441544
#?@(:clj [(and f-meta (:sci.impl.analyzer/interop f-meta))
1545-
(let [[obj & children] (analyze-children ctx (rest expr))
1545+
(let [[obj & args] (analyze-children ctx (rest expr))
15461546
meth (-> (second f)
15471547
str
15481548
(subs 1))
15491549
clazz (first f)
1550-
children (into-array Object children)
1551-
child-count (count children)
1550+
args (object-array args)
1551+
arg-count (count args)
15521552
stack (assoc m
15531553
:ns @utils/current-ns
15541554
:file @utils/current-file
1555-
:sci.impl/f-meta f-meta)]
1555+
:sci.impl/f-meta f-meta)
1556+
^"[Ljava.lang.Class;" arg-types (when (pos? arg-count)
1557+
(make-array Class arg-count))
1558+
has-types? (volatile! nil)]
1559+
(when arg-types
1560+
(areduce args idx _ret nil
1561+
(let [arg (aget args idx)
1562+
arg-meta (meta arg)]
1563+
(when-let [t (:tag arg-meta)]
1564+
(when-let [t (interop/resolve-type-hint ctx t)]
1565+
(do (vreset! has-types? true)
1566+
(aset arg-types idx t)))))))
15561567
(sci.impl.types/->Node
15571568
(let [obj (sci.impl.types/eval obj ctx bindings)]
15581569
(interop/invoke-instance-method ctx bindings obj clazz
15591570
meth
1560-
children child-count nil))
1571+
args arg-count arg-types))
15611572
stack))])
15621573
#?@(:clj [(and f-meta (:sci.impl.analyzer/invoke-constructor f-meta))
15631574
(invoke-constructor-node ctx (first f) (rest expr))])

test/sci/interop_test.cljc

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,14 @@
338338
#?(:cljs (deftest local-interop-test
339339
(is (= 1 (tu/eval* "(let [j #js {:a (fn [] 1)}] (j.a))" nil)))))
340340

341-
#?(:clj (def type-hint-config {:classes {'java.util.concurrent.Executors java.util.concurrent.Executors 'java.util.concurrent.ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor 'java.util.concurrent.Callable java.util.concurrent.Callable 'java.util.concurrent.FutureTask java.util.concurrent.FutureTask 'java.lang.Runnable java.lang.Runnable}}))
341+
#?(:clj (def type-hint-config {:classes {'java.util.concurrent.Executors java.util.concurrent.Executors
342+
'java.util.concurrent.ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor
343+
'java.util.concurrent.Callable java.util.concurrent.Callable
344+
'java.util.concurrent.FutureTask java.util.concurrent.FutureTask
345+
'java.lang.Runnable java.lang.Runnable
346+
'java.util.concurrent.ExecutorService java.util.concurrent.ExecutorService}
347+
:imports {'Runnable 'java.lang.Runnable
348+
'Callable 'java.util.concurrent.Callable}}))
342349

343350
#?(:clj
344351
(deftest type-hint-test
@@ -365,14 +372,22 @@
365372
(testing "type hinting fn argument with callable returns nil on futuretask get"
366373
(is (= 3 (sci/eval-string "(defn fut [^java.util.concurrent.Callable f] (.submit (java.util.concurrent.Executors/newCachedThreadPool) f)) (.get (fut (fn [] 3)))" type-hint-config))))
367374
(testing "type hinting on fn expression as argument with Callable returns nil on futuretask get"
368-
(is (= 3 (sci/eval-string "(def fut (.submit (java.util.concurrent.Executors/newCachedThreadPool) ^java.util.concurrent.Callable (fn [] 3))) (.get fut)" type-hint-config)))))
375+
(is (= 3 (sci/eval-string "(def fut (.submit (java.util.concurrent.Executors/newCachedThreadPool) ^java.util.concurrent.Callable (fn [] 3))) (.get fut)" type-hint-config))))
376+
(testing "similar cases but with qualified interop"
377+
(is (nil? (sci/eval-string "(def ^java.util.concurrent.ExecutorService thread-pool (java.util.concurrent.Executors/newCachedThreadPool))
378+
@(java.util.concurrent.ExecutorService/.submit thread-pool ^Runnable (fn [] 3))"
379+
type-hint-config)))
380+
(is (= 3 (sci/eval-string "(def ^java.util.concurrent.ExecutorService thread-pool (java.util.concurrent.Executors/newCachedThreadPool))
381+
@(java.util.concurrent.ExecutorService/.submit thread-pool ^Callable (fn [] 3))"
382+
type-hint-config)))))
369383
(testing "type hint on interop argument"
370384
;; this test assumes clojure/core.clj comes from a jar file
371385
;; the test will fail when not processing the type hint on the interop argument
372386
(sci/eval-string "(.getJarEntry ^java.net.JarURLConnection (.openConnection resource))"
373387
{:bindings {'resource (io/resource "clojure/core.clj")}
374388
:classes {'java.net.URL java.net.URL
375-
'java.net.JarURLConnection java.net.JarURLConnection}}))))
389+
'java.net.JarURLConnection java.net.JarURLConnection}}))
390+
))
376391

377392
#?(:cljs
378393
(deftest issue-987-munged-property-name-test

0 commit comments

Comments
 (0)