Skip to content

Commit 2ad1470

Browse files
mfikesdnolen
authored andcommitted
CLJS-1871: A declare with :arglists should generate static function calls
1 parent 56ea8ee commit 2ad1470

File tree

8 files changed

+59
-22
lines changed

8 files changed

+59
-22
lines changed

src/main/cljs/cljs/js.cljs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@
194194
;; -----------------------------------------------------------------------------
195195
;; Analyze
196196

197-
(declare eval-str*)
197+
(declare ^{:arglists '([bound-vars source name opts cb])} eval-str*)
198198

199199
(def *loaded* (atom #{}))
200200

@@ -217,7 +217,10 @@
217217
(run-async! proc (rest coll) break? cb))))
218218
(cb nil)))
219219

220-
(declare require)
220+
(declare ^{:arglists '([name cb]
221+
[name opts cb]
222+
[bound-vars name opts cb]
223+
[bound-vars name reload opts cb])} require)
221224

222225
(defn- process-deps
223226
[bound-vars names opts cb]
@@ -426,7 +429,7 @@
426429
(cb res))))))
427430
(cb {:value nil})))))))
428431

429-
(declare analyze-str*)
432+
(declare ^{:arglists '([bound-vars source name opts cb])} analyze-str*)
430433

431434
(defn- analyze-deps
432435
([bound-vars ana-env lib deps cb]
@@ -786,7 +789,7 @@
786789
;; -----------------------------------------------------------------------------
787790
;; Eval
788791

789-
(declare clear-fns!)
792+
(declare ^{:arglists '([])} clear-fns!)
790793

791794
(defn- eval* [bound-vars form opts cb]
792795
(let [the-ns (or (:ns opts) 'cljs.user)

src/main/cljs/cljs/pprint.cljs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ beginning of aseq"
221221
;; Forward declarations
222222
;;======================================================================
223223

224-
(declare get-miser-width)
224+
(declare ^{:arglists '([this])} get-miser-width)
225225

226226
;;======================================================================
227227
;; The data structures used by pretty-writer
@@ -687,7 +687,7 @@ radix specifier is in the form #XXr where XX is the decimal value of *print-base
687687
;; Support for the write function
688688
;;======================================================================
689689

690-
(declare format-simple-number)
690+
(declare ^{:arglists '([n])} format-simple-number)
691691

692692
;; This map causes var metadata to be included in the compiled output, even
693693
;; in advanced compilation. See CLJS-1853 - António Monteiro
@@ -887,9 +887,9 @@ THIS FUNCTION IS NOT YET IMPLEMENTED."
887887
;;======================================================================
888888

889889
;; Forward references
890-
(declare compile-format)
891-
(declare execute-format)
892-
(declare init-navigator)
890+
(declare ^{:arglists '([format-str])} compile-format)
891+
(declare ^{:arglists '([stream format args] [format args])} execute-format)
892+
(declare ^{:arglists '([s])} init-navigator)
893893
;; End forward references
894894

895895
(defn cl-format
@@ -1026,7 +1026,7 @@ http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm"
10261026
;; Common handling code for ~A and ~S
10271027
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10281028

1029-
(declare opt-base-str)
1029+
(declare ^{:arglists '([base val])} opt-base-str)
10301030

10311031
(def ^{:private true}
10321032
special-radix-markers {2 "#b" 8 "#o" 16 "#x"})
@@ -1832,8 +1832,8 @@ http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm"
18321832
;; TODO: make it possible to make these decisions at compile-time.
18331833
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18341834

1835-
(declare format-logical-block)
1836-
(declare justify-clauses)
1835+
(declare ^{:arglists '([params navigator offsets])} format-logical-block)
1836+
(declare ^{:arglists '([params navigator offsets])} justify-clauses)
18371837

18381838
(defn- logical-block-or-justify [params navigator offsets]
18391839
(if (:colon (:right-params params))
@@ -2572,7 +2572,7 @@ of parameters as well."
25722572
(and (:separator (:bracket-info (:def this)))
25732573
(:colon (:params this))))
25742574

2575-
(declare collect-clauses)
2575+
(declare ^{:arglists '([bracket-info offset remainder])} collect-clauses)
25762576

25772577
(defn- process-bracket [this remainder]
25782578
(let [[subex remainder] (collect-clauses (:bracket-info (:def this))
@@ -2918,7 +2918,7 @@ type-map {"core$future_call" "Future",
29182918
;;; Dispatch for the code table
29192919
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29202920

2921-
(declare pprint-simple-code-list)
2921+
(declare ^{:arglists '([alis])} pprint-simple-code-list)
29222922

29232923
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29242924
;;; Format the namespace ("ns") macro. This is quite complicated because of all the

src/main/cljs/cljs/spec/alpha.cljs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@
9999
(implements? IMeta spec)
100100
(-> (meta spec) ::name)))
101101

102-
(declare spec-impl)
103-
(declare regex-spec-impl)
102+
(declare ^{:arglists '([form pred gfn cpred?] [form pred gfn cpred? unc])} spec-impl)
103+
(declare ^{:arglists '([re gfn])} regex-spec-impl)
104104

105105
(defn- maybe-spec
106106
"spec-or-k must be a spec, regex or resolvable kw/sym, else returns nil."
@@ -264,7 +264,7 @@
264264
[spec x]
265265
(with-out-str (explain spec x)))
266266

267-
(declare valid?)
267+
(declare ^{:arglists '([spec x] [spec x form])} valid?)
268268

269269
(defn- gensub
270270
[spec overrides path rmap form]
@@ -1004,7 +1004,7 @@
10041004
(empty? pret))
10051005
nil))
10061006

1007-
(declare preturn)
1007+
(declare ^{:arglists '([p])} preturn)
10081008

10091009
(defn- accept-nil? [p]
10101010
(let [{:keys [::op ps p1 p2 forms] :as p} (reg-resolve! p)]
@@ -1019,7 +1019,7 @@
10191019
::pcat (every? accept-nil? ps)
10201020
::alt (c/some accept-nil? ps))))
10211021

1022-
(declare add-ret)
1022+
(declare ^{:arglists '([p r k])} add-ret)
10231023

10241024
(defn- preturn [p]
10251025
(let [{[p0 & pr :as ps] :ps, [k :as ks] :ks, :keys [::op p1 ret forms] :as p} (reg-resolve! p)]

src/main/cljs/clojure/data.cljs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
clojure.data
1313
(:require [clojure.set :as set]))
1414

15-
(declare diff)
15+
(declare ^{:arglists '([a b])} diff)
1616

1717
(defn- atom-diff
1818
"Internal helper for diff."

src/main/clojure/cljs/analyzer.cljc

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
:fn-var true
132132
:fn-arity true
133133
:fn-deprecated true
134+
:declared-arglists-mismatch true
134135
:protocol-deprecated true
135136
:undeclared-protocol-symbol true
136137
:invalid-protocol-symbol true
@@ -347,6 +348,12 @@
347348
[warning-type info]
348349
(str (-> info :fexpr :info :name) " is deprecated"))
349350

351+
(defmethod error-message :declared-arglists-mismatch
352+
[warning-type info]
353+
(str (symbol (str (:ns-name info)) (str (:sym info)))
354+
" declared arglists " (:declared info)
355+
" mismatch defined arglists " (:defined info)))
356+
350357
(defmethod error-message :undeclared-ns-form
351358
[warning-type info]
352359
(str "Invalid :refer, " (:type info) " " (:lib info) "/" (:sym info) " does not exist"))
@@ -1527,7 +1534,13 @@
15271534
(not (:declared sym-meta))
15281535
*file-defs*
15291536
(get @*file-defs* sym))
1530-
(warning :redef-in-file env {:sym sym :line (:line v)})))
1537+
(warning :redef-in-file env {:sym sym :line (:line v)}))
1538+
(when (and (:declared v)
1539+
(:arglists v)
1540+
(not= (:arglists v) (:arglists sym-meta)))
1541+
(warning :declared-arglists-mismatch env {:ns-name ns-name :sym sym
1542+
:declared (second (:arglists v))
1543+
:defined (second (:arglists sym-meta))})))
15311544
(let [env (if (or (and (not= ns-name 'cljs.core)
15321545
(core-name? env sym))
15331546
(some? (get-in @env/*compiler* [::namespaces ns-name :uses sym])))
@@ -1617,6 +1630,11 @@
16171630
:method-params params
16181631
:arglists (:arglists sym-meta)
16191632
:arglists-meta (doall (map meta (:arglists sym-meta)))}))))
1633+
(when (and (:declared sym-meta)
1634+
(:arglists sym-meta))
1635+
{:declared true
1636+
:fn-var true
1637+
:method-params (second (:arglists sym-meta))})
16201638
(if (and fn-var? (some? tag))
16211639
{:ret-tag tag}
16221640
(when tag {:tag tag})))))

src/test/cljs/cljs/invoke_test.cljs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@
3030
(gstr/urlEncode "foo")
3131

3232
(js/goog.string.urlDecode "bar")
33+
34+
(declare ^{:arglists '([a b])} declared-fn)
35+
36+
(declared-fn 1 2)

src/test/clojure/cljs/analyzer_tests.clj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,16 @@
712712
z)))))
713713
:tag meta :prefix))))
714714

715+
(deftest test-cljs-1871
716+
(let [ws (atom [])]
717+
(try
718+
(a/with-warning-handlers [(collecting-warning-handler ws)]
719+
(a/analyze (ana/empty-env)
720+
'(do (declare ^{:arglists '([x y])} foo)
721+
(defn foo [x]))))
722+
(catch Exception _))
723+
(is (string/includes? (first @ws) "declared arglists ([x y]) mismatch defined arglists ([x])"))))
724+
715725
(deftest test-cljs-2023
716726
(let [form (with-meta 'js/goog.DEBUG {:tag 'boolean})]
717727
(is (= (-> (ana-api/analyze (a/empty-env) form) :tag) 'boolean))))

src/test/clojure/cljs/compiler_tests.clj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,9 @@
266266
(is (re-find #"(?m)^.*var fexpr.*=.*cljs.core.complement\(funexpr1\);$"
267267
content))
268268
(is (re-find #"(?m)^.*var .*=.*inv_arg1.cljs.core.IFn._invoke.arity.0 \?.*$"
269-
content)))))
269+
content))
270+
;; CLJS-1871: A declare hinted with :arglists meta should result in static dispatch
271+
(is (str/includes? content "cljs.invoke_test.declared_fn(")))))
270272
#_(test-vars [#'test-optimized-invoke-emit])
271273

272274
;; CLJS-1225

0 commit comments

Comments
 (0)