(defn parse-deftype*
[[_ name class-name fields _ interfaces & methods :as form] env]
(let [interfaces (disj (set (mapv maybe-class interfaces)) Object)
fields-expr (mapv (fn [name]
{:env env
:form name
:name name
:mutable (let [m (meta name)]
(or (and (:unsynchronized-mutable m)
:unsynchronized-mutable)
(and (:volatile-mutable m)
:volatile-mutable)))
:local :field
:op :binding})
fields)
menv (assoc env
:context :ctx/expr
:locals (zipmap fields (map dissoc-env fields-expr))
:this class-name)
[opts methods] (parse-opts+methods methods)
methods (mapv #(assoc (analyze-method-impls % menv) :interfaces interfaces)
methods)]
(-deftype name class-name fields interfaces)
{:op :deftype
:env env
:form form
:name name
:class-name class-name ;; internal, don't use as a Class
:fields fields-expr
:methods methods
:interfaces interfaces
:children [:fields :methods]}))