Permalink
Browse files

CLJS-627: Add warnings on function arity problems

This patch adds three new warning types that may be thrown when
defining a function.

:multiple-variadic-overloads : Can't have more than 1 variadic overload
:variadic-max-arity : Can't have fixed arity with more params than
variadic
:overload-arity : Can't have 2 overloads with the same arity
  • Loading branch information...
thieman authored and swannodette committed Nov 4, 2013
1 parent 9ab2bff commit 55ee7fd58c23ff2c2950fdf3357257b71e967edf
Showing with 26 additions and 5 deletions.
  1. +26 −5 src/clj/cljs/analyzer.clj
View
@@ -40,7 +40,10 @@
:fn-deprecated true
:protocol-deprecated true
:undeclared-protocol-symbol true
- :invalid-protocol-symbol true})
+ :invalid-protocol-symbol true
+ :multiple-variadic-overloads true
+ :variadic-max-arity true
+ :overload-arity true})
(declare message namespaces)
@@ -98,6 +101,18 @@
[warning-type extra]
(str "Symbol " (:protocol extra) " is not a protocol"))
+(defmethod default-warning-handler* :multiple-variadic-overloads
+ [warning-type extra]
+ (str (:name extra) ": Can't have more than 1 variadic overload"))
+
+(defmethod default-warning-handler* :variadic-max-arity
+ [warning-type extra]
+ (str (:name extra) ": Can't have fixed arity function with more params than variadic function"))
+
+(defmethod default-warning-handler* :overload-arity
+ [warning-type extra]
+ (str (:name extra) ": Can't have 2 overloads with same arity"))
+
(defn ^:private default-warning-handler [warning-type env extra]
(when (warning-type *cljs-warnings*)
(when-let [s (default-warning-handler* warning-type extra)]
@@ -562,10 +577,16 @@
;; lets us optimize self calls
(no-warn (doall (map #(analyze-fn-method menv locals % type) meths)))
methods)]
- ;;todo - at most one variadic, variadic takes max required args
- (let [param-counts (map (comp count :params) methods)]
- (when (not= (distinct param-counts) param-counts)
- (throw (error env "Can't have 2 overloads with same arity"))))
+ (let [variadic-methods (filter :variadic methods)
+ variadic-params (count (:params (first variadic-methods)))
+ param-counts (map (comp count :params) methods)]
+ (when (and (:multiple-variadic-overloads *cljs-warnings*) (< 1 (count variadic-methods)))
+ (warning :multiple-variadic-overloads env {:name name-var}))
+ (when (and (:variadic-max-arity *cljs-warnings*)
+ (not (or (zero? variadic-params) (= variadic-params (+ 1 max-fixed-arity)))))
+ (warning :variadic-max-arity env {:name name-var}))
+ (when (and (:overload-arity *cljs-warnings*) (not= (distinct param-counts) param-counts))
+ (warning :overload-arity env {:name name-var})))
{:env env :op :fn :form form :name name-var :methods methods :variadic variadic
:recur-frames *recur-frames* :loop-lets *loop-lets*
:jsdoc [(when variadic "@param {...*} var_args")]

0 comments on commit 55ee7fd

Please sign in to comment.