diff --git a/src/sci/impl/analyzer.cljc b/src/sci/impl/analyzer.cljc index 1bd25f91..e3d5e78e 100644 --- a/src/sci/impl/analyzer.cljc +++ b/src/sci/impl/analyzer.cljc @@ -1482,6 +1482,38 @@ ns (analyze-ns-form ctx expr) lazy-seq (analyze-lazy-seq ctx expr))) +#?(:clj + (defn analyze-instance-method-interop [_ctx _expr ^Class _class meth] + (fn [obj & args] + (Reflector/invokeInstanceMethod + obj meth + ^objects (into-array Object args))))) + +#?(:clj + (defn analyze-interop [ctx expr [^Class clazz meth]] + (let [meth (str meth) + stack (assoc (meta expr) + :ns @utils/current-ns + :file @utils/current-file)] + (if-let [_fld (try (Reflector/getStaticField ^Class clazz ^String meth) + (catch IllegalArgumentException _ + nil))] + (sci.impl.types/->Node + (interop/get-static-field clazz meth) + stack) + (if (str/starts-with? meth ".") + (let [meth (subs meth 1) + f (analyze-instance-method-interop ctx expr class meth)] + (sci.impl.types/->Node + f + stack)) + (sci.impl.types/->Node + (fn [& args] + (Reflector/invokeStaticMethod + clazz meth + ^objects (into-array Object args))) + stack)))))) + (defn analyze-call [ctx expr m top-level?] (with-top-level-loc top-level? m (let [eval-file (:clojure.core/eval-file m)] @@ -1552,6 +1584,18 @@ method (unchecked-get class method-name)] (interop/invoke-static-method ctx bindings class method children)) nil))))) + (and f-meta (:sci.impl.analyzer/interop f-meta)) + (let [f (analyze-instance-method-interop nil expr nil (-> (second f) + str + (subs 1)))] + (return-call ctx + expr + f (analyze-children ctx (rest expr)) + (assoc m + :ns @utils/current-ns + :file @utils/current-file + :sci.impl/f-meta f-meta) + nil)) (and (not eval?) ;; the symbol is not a binding (symbol? f) (or @@ -1801,33 +1845,6 @@ arr) nil)))))) -#?(:clj - (defn analyze-interop [_ctx expr [^Class clazz meth]] - (let [meth (str meth) - stack (assoc (meta expr) - :ns @utils/current-ns - :file @utils/current-file)] - (if-let [_fld (try (Reflector/getStaticField ^Class clazz ^String meth) - (catch IllegalArgumentException _ - nil))] - (sci.impl.types/->Node - (interop/get-static-field clazz meth) - stack) - (if (str/starts-with? meth ".") - (let [meth (subs meth 1)] - (sci.impl.types/->Node - (fn [obj & args] - (Reflector/invokeInstanceMethod - obj meth - ^objects (into-array Object args))) - stack)) - (sci.impl.types/->Node - (fn [& args] - (Reflector/invokeStaticMethod - clazz meth - ^objects (into-array Object args))) - stack)))))) - #?(:clj (comment (def meths (.getMethods Integer)) diff --git a/src/sci/impl/resolve.cljc b/src/sci/impl/resolve.cljc index 3eec4655..47061e98 100644 --- a/src/sci/impl/resolve.cljc +++ b/src/sci/impl/resolve.cljc @@ -67,7 +67,7 @@ (or (some-> env :namespaces (get sym-ns) (find sym-name)) (when-not only-var? (when-let [clazz (interop/resolve-class ctx sym-ns)] - [sym (if call? + [sym (if (and call? #?(:clj (not (str/starts-with? sym-name-str ".")))) (with-meta [clazz #?(:clj sym-name :cljs (.split (str sym-name) "."))] diff --git a/test/sci/interop_test.cljc b/test/sci/interop_test.cljc index 7a6d3acc..d21395b9 100644 --- a/test/sci/interop_test.cljc +++ b/test/sci/interop_test.cljc @@ -124,7 +124,8 @@ (deftest clojure-1_12-interop-test (is (= [1 2 3] (eval* "(map Integer/parseInt [\"1\" \"2\" \"3\"])"))) (is (= [1 2 3] (eval* "(map String/.length [\"1\" \"22\" \"333\"])"))) - (is (= ["1" "22" "333"] (eval* "(map String/new [\"1\" \"22\" \"333\"])"))))) + (is (= ["1" "22" "333"] (eval* "(map String/new [\"1\" \"22\" \"333\"])"))) + (is (= 3 (eval* "(String/.length \"123\")"))))) #?(:clj (when-not tu/native?