|
12 | 12 |
|
13 | 13 | (defn process-method-value |
14 | 14 | "Transforms :invoke nodes whose :fn is a :method-value into the |
15 | | - corresponding :instance-call, :static-call, or :new node. " |
| 15 | + corresponding :instance-call, :static-call, or :new node. |
| 16 | + Also converts value-position :method-value nodes with a |
| 17 | + :field-overload (and no :param-tags) into :static-field nodes." |
16 | 18 | {:pass-info {:walk :post :depends #{#'analyze-host-expr}}} |
17 | 19 | [{:keys [op args env] :as ast}] |
18 | | - (if (and (= :invoke op) |
19 | | - (= :method-value (:op (:fn ast)))) |
20 | | - (let [{:keys [class method kind param-tags]} (:fn ast)] |
21 | | - (when (and (= :instance kind) (empty? args)) |
| 20 | + (cond |
| 21 | + (and (= :invoke op) |
| 22 | + (= :method-value (:op (:fn ast)))) |
| 23 | + (let [{:keys [class method kind param-tags methods]} (:fn ast) |
| 24 | + instance? (= :instance kind) |
| 25 | + call-args (if instance? (vec (rest args)) args) |
| 26 | + argc (count call-args) |
| 27 | + methods (seq (filter #(= argc (count (:parameter-types %))) methods))] |
| 28 | + (when (and instance? (empty? args)) |
22 | 29 | (throw (ex-info (str "Qualified instance method " (.getName ^Class class) "/." method |
23 | 30 | " must have a target") |
24 | 31 | (merge {:class class :method method} |
|
30 | 37 | :method method |
31 | 38 | :class class |
32 | 39 | :instance (first args) |
33 | | - :args (vec (rest args)) |
| 40 | + :args call-args |
34 | 41 | :children [:instance :args]} |
35 | 42 |
|
36 | 43 | :static |
37 | 44 | {:op :static-call |
38 | 45 | :method method |
39 | 46 | :class class |
40 | | - :args args |
| 47 | + :args call-args |
41 | 48 | :children [:args]} |
42 | 49 |
|
43 | 50 | :ctor |
44 | 51 | {:op :new |
45 | 52 | :class {:op :const :type :class :val class |
46 | 53 | :form class :env env} |
47 | | - :args args |
| 54 | + :args call-args |
48 | 55 | :children [:class :args]}) |
49 | 56 | (when param-tags |
50 | | - {:param-tags param-tags}))) |
51 | | - ast)) |
| 57 | + {:param-tags param-tags}) |
| 58 | + (when methods |
| 59 | + {:methods (vec methods)}))) |
| 60 | + |
| 61 | + (and (= :method-value op) |
| 62 | + (:field-overload ast) |
| 63 | + (not (:param-tags ast))) |
| 64 | + (let [{:keys [flags type name]} (:field-overload ast)] |
| 65 | + {:op :static-field |
| 66 | + :assignable? (not (:final flags)) |
| 67 | + :class (:class ast) |
| 68 | + :field name |
| 69 | + :form (:form ast) |
| 70 | + :env env |
| 71 | + :o-tag type |
| 72 | + :tag (or (:tag ast) type)}) |
| 73 | + |
| 74 | + :else ast)) |
0 commit comments