Browse files

CLJS-639: warning when records initialized incorrectly

When not a defrecord internal constructor call check the arity of the
instantiation form against the fields - ignoring extmap, meta and
hash. This is done by setting :internal-ctor meta on the record symbol,
otherwise the logic is identical to deftype*. Fix some formatting.
  • Loading branch information...
1 parent 34821a2 commit 8c6dd2468a3913e316d021fc0b09745bd3ac7dcd @swannodette swannodette committed Nov 19, 2013
Showing with 16 additions and 11 deletions.
  1. +7 −3 src/clj/cljs/analyzer.clj
  2. +9 −8 src/clj/cljs/core.clj
View
10 src/clj/cljs/analyzer.clj
@@ -758,9 +758,10 @@
argexprs (vec (map #(analyze enve %) args))
known-num-fields (:num-fields (resolve-existing-var env ctor))
argc (count args)]
- (when (and known-num-fields (not= known-num-fields argc) (:fn-arity *cljs-warnings*))
+ (when (and (:fn-arity *cljs-warnings*)
+ (not (-> ctor meta :internal-ctor))
+ known-num-fields (not= known-num-fields argc))
(warning :fn-arity env {:argc argc :ctor ctor}))
-
{:env env :op :new :form form :ctor ctorexpr :args argexprs
:children (into [ctorexpr] argexprs)})))
@@ -961,7 +962,10 @@
(let [t (:name (resolve-var (dissoc env :locals) tsym))]
(swap! env/*compiler* update-in [::namespaces (-> env :ns :name) :defs tsym]
(fn [m]
- (let [m (assoc (or m {}) :name t :type true)]
+ (let [m (assoc (or m {})
+ :name t
+ :type true
+ :num-fields (count fields))]
(merge m
{:protocols (-> tsym meta :protocols)}
(source-info tsym env)))))
View
17 src/clj/cljs/core.clj
@@ -908,18 +908,19 @@
(~'defrecord* ~tagname ~hinted-fields ~pmasks)
(extend-type ~tagname ~@(dt->et tagname impls fields true))))))
-(defn- build-map-factory
- [rsym rname fields]
+(defn- build-map-factory [rsym rname fields]
(let [fn-name (symbol (core/str 'map-> rsym))
- ms (gensym)
- ks (map keyword fields)
- getters (map (fn [k] `(~k ~ms)) ks)]
- `(defn ~fn-name
- [~ms]
+ ms (gensym)
+ ks (map keyword fields)
+ getters (map (fn [k] `(~k ~ms)) ks)]
+ `(defn ~fn-name [~ms]
(new ~rname ~@getters nil (dissoc ~ms ~@ks)))))
(defmacro defrecord [rsym fields & impls]
- (let [r (:name (cljs.analyzer/resolve-var (dissoc &env :locals) rsym))]
+ (let [rsym (vary-meta rsym assoc :internal-ctor true)
+ r (vary-meta
+ (:name (cljs.analyzer/resolve-var (dissoc &env :locals) rsym))
+ assoc :internal-ctor true)]
`(let []
~(emit-defrecord &env rsym r fields impls)
(set! (.-cljs$lang$type ~r) true)

0 comments on commit 8c6dd24

Please sign in to comment.