Skip to content

Commit 77e01a0

Browse files
thhellerdnolen
authored andcommitted
Fix assumption that all closure-compliant JS is goog.*
When using other Closure-compatible JS libs the compiler would otherwise try to emit CLJS-styles invokes. Expected: somefn(1) Actual: somefn.cljs$core$IFn$_invoke$arity$1 ? ... : somefn.call(null, 1) This is a CLJS idiom and should only be emitted if we have analyzer data for the given namespace.
1 parent 5cc7865 commit 77e01a0

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

src/main/clojure/cljs/compiler.cljc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,9 @@
951951
goog? (when ns
952952
(or (= ns 'goog)
953953
(when-let [ns-str (str ns)]
954-
(= (get (string/split ns-str #"\.") 0 nil) "goog"))))
954+
(= (get (string/split ns-str #"\.") 0 nil) "goog"))
955+
(not (contains? (::ana/namespaces @env/*compiler*) ns))))
956+
955957
keyword? (and (= (-> f :op) :constant)
956958
(keyword? (-> f :form)))
957959
[f variadic-invoke]

src/test/cljs/cljs/invoke_test.cljs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
(ns cljs.invoke-test
2+
(:require [goog.string :as gstr]))
3+
4+
(defn variadic-fn [& args])
5+
6+
(variadic-fn 1 2 3)
7+
8+
(defn multi-fn
9+
([a] a)
10+
([a b] a))
11+
12+
(multi-fn 2)
13+
14+
(gstr/urlEncode "foo")
15+
16+
(js/goog.string.urlDecode "bar")

src/test/clojure/cljs/compiler_tests.clj

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
(:use clojure.test)
1111
(:require [cljs.analyzer :as ana]
1212
[cljs.compiler :as comp]
13+
[cljs.compiler.api :as comp-api]
1314
[cljs.env :as env]
1415
[cljs.util :as util]
15-
[cljs.tagged-literals :as tags])
16+
[cljs.tagged-literals :as tags]
17+
[clojure.java.io :as io]
18+
[clojure.string :as str])
1619
(:import [java.io File]))
1720

1821
(def aenv (assoc-in (ana/empty-env) [:ns :name] 'cljs.user))
@@ -215,6 +218,28 @@
215218
opts
216219
(fn [] (ana/analyze aenv specify-test-code nil opts))))))))))))
217220

221+
222+
(deftest test-optimized-invoke-emit
223+
(let [out-file
224+
(io/file "target/invoke_test.js")]
225+
(comp-api/with-core-cljs
226+
(comp-api/compile-file
227+
(io/file "src/test/cljs/cljs/invoke_test.cljs")
228+
out-file
229+
{:static-fns true}))
230+
231+
(let [content (slurp out-file)]
232+
;; test for fn( not fn.call(, omitting arguments in test because they are not relevant
233+
;; should emit variadic invokes
234+
(is (str/includes? content "cljs.invoke_test.variadic_fn.cljs$core$IFn$_invoke$arity$variadic("))
235+
;; should emit optimized invokes
236+
(is (str/includes? content "cljs.invoke_test.multi_fn.cljs$core$IFn$_invoke$arity$1("))
237+
;; closure js code must never use .call(
238+
(is (str/includes? content "goog.string.urlEncode("))
239+
;; js/goog.string.urlDecode should not use .call
240+
(is (str/includes? content "goog.string.urlDecode(")))
241+
))
242+
218243
;; CLJS-1225
219244

220245
(comment

0 commit comments

Comments
 (0)