Skip to content

Commit a0d85cf

Browse files
fdserrdnolen
authored andcommitted
FIX CLJS-1445 Syntax error for var args in protocol methods
- add warning key :protocol-with-variadic-method - add defmethod error-message - warn if '& found in protocol sigs
1 parent 89b1a31 commit a0d85cf

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed

src/main/clojure/cljs/analyzer.cljc

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
:refer [no-warn wrapping-errors
1515
disallowing-recur allowing-redef]]
1616
[cljs.env.macros :refer [ensure]]))
17-
#?(:clj (:require [cljs.util :as util :refer [ns->relpath topo-sort]]
17+
#?(:clj (:require [cljs.util :as util :refer [ns->relpath topo-sort]]
1818
[clojure.java.io :as io]
1919
[clojure.string :as string]
2020
[clojure.set :as set]
@@ -83,6 +83,7 @@
8383
:protocol-invalid-method true
8484
:protocol-duped-method true
8585
:protocol-multiple-impls true
86+
:protocol-with-variadic-method true
8687
:single-segment-namespace true
8788
:munged-namespace true
8889
:ns-var-clash true
@@ -294,6 +295,11 @@
294295
[warning-type info]
295296
(str "Protocol " (:protocol info) " implemented multiple times"))
296297

298+
(defmethod error-message :protocol-with-variadic-method
299+
[warning-type info]
300+
(str "Protocol " (:protocol info) " declares method "
301+
(:name info) " with variadic signature (&)"))
302+
297303
(defmethod error-message :multiple-variadic-overloads
298304
[warning-type info]
299305
(str (:name info) ": Can't have more than 1 variadic overload"))
@@ -1142,7 +1148,7 @@
11421148
(and (:fn-var v) (not fn-var?)))
11431149
(warning :fn-var env {:ns-name ns-name :sym sym})))
11441150
(swap! env/*compiler* assoc-in [::namespaces ns-name :defs sym]
1145-
(merge
1151+
(merge
11461152
{:name var-name}
11471153
;; remove actual test metadata, as it includes non-valid EDN and
11481154
;; cannot be present in analysis cached to disk - David
@@ -1503,7 +1509,7 @@
15031509

15041510
(defn analyze-let
15051511
[encl-env [_ bindings & exprs :as form] is-loop]
1506-
(when-not (and (vector? bindings) (even? (count bindings)))
1512+
(when-not (and (vector? bindings) (even? (count bindings)))
15071513
(throw (error encl-env "bindings must be vector of even number of elements")))
15081514
(let [context (:context encl-env)
15091515
[bes env] (analyze-let-bindings encl-env bindings)
@@ -1538,9 +1544,9 @@
15381544
(let [context (:context env)
15391545
frame (first *recur-frames*)
15401546
exprs (disallowing-recur (vec (map #(analyze (assoc env :context :expr) %) exprs)))]
1541-
(when-not frame
1547+
(when-not frame
15421548
(throw (error env "Can't recur here")))
1543-
(when-not (= (count exprs) (count (:params frame)))
1549+
(when-not (= (count exprs) (count (:params frame)))
15441550
(throw (error env "recur argument count mismatch")))
15451551
(reset! (:flag frame) true)
15461552
(assoc {:env env :op :recur :form form}
@@ -1554,7 +1560,7 @@
15541560

15551561
(defmethod parse 'new
15561562
[_ env [_ ctor & args :as form] _ _]
1557-
(when-not (symbol? ctor)
1563+
(when-not (symbol? ctor)
15581564
(throw (error env "First arg to new must be a symbol")))
15591565
(disallowing-recur
15601566
(let [enve (assoc env :context :expr)
@@ -1616,7 +1622,7 @@
16161622
(when (:field targetexpr)
16171623
targetexpr))))
16181624
valexpr (analyze enve val)]
1619-
(when-not targetexpr
1625+
(when-not targetexpr
16201626
(throw (error env "set! target must be a field or a symbol naming a var")))
16211627
(cond
16221628
(= targetexpr ::set-unchecked-if) {:env env :op :no-op}
@@ -1729,7 +1735,7 @@
17291735
(fn [s [k exclude xs]]
17301736
(if (= k :refer-clojure)
17311737
(do
1732-
(when-not (= exclude :exclude)
1738+
(when-not (= exclude :exclude)
17331739
(throw (error env "Only [:refer-clojure :exclude (names)] form supported")))
17341740
(when (seq s)
17351741
(throw (error env "Only one :refer-clojure form is allowed per namespace definition")))
@@ -1883,7 +1889,7 @@
18831889

18841890
(defmethod parse 'ns
18851891
[_ env [_ name & args :as form] _ opts]
1886-
(when-not (symbol? name)
1892+
(when-not (symbol? name)
18871893
(throw (error env "Namespaces must be named by a symbol.")))
18881894
(let [name (cond-> name (:macros-ns opts) macro-ns-name)]
18891895
(let [segments (string/split (clojure.core/name name) #"\.")]

src/main/clojure/cljs/core.cljc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,10 @@
18931893
(core/let [doc (core/as-> (last sigs) doc
18941894
(core/when (core/string? doc) doc))
18951895
sigs (take-while vector? sigs)
1896+
amp (when (some #{'&} (apply concat sigs))
1897+
(cljs.analyzer/warning
1898+
:protocol-with-variadic-method
1899+
&env {:protocol psym :name fname}))
18961900
slot (symbol (core/str prefix (name fname)))
18971901
fname (vary-meta fname assoc
18981902
:protocol p
@@ -2143,7 +2147,7 @@
21432147
thens (vec (vals pairs))]
21442148
`(let [~esym (if (keyword? ~e) (.-fqn ~e) nil)]
21452149
(case* ~esym ~tests ~thens ~default)))
2146-
2150+
21472151
;; equality
21482152
:else
21492153
`(let [~esym ~e]
@@ -2579,7 +2583,7 @@
25792583
(core/defmacro lazy-cat
25802584
"Expands to code which yields a lazy sequence of the concatenation
25812585
of the supplied colls. Each coll expr is not evaluated until it is
2582-
needed.
2586+
needed.
25832587
25842588
(lazy-cat xs ys zs) === (concat (lazy-seq xs) (lazy-seq ys) (lazy-seq zs))"
25852589
[& colls]

0 commit comments

Comments
 (0)