diff options
author | Eduardo Julian | 2015-12-06 19:10:38 -0400 |
---|---|---|
committer | Eduardo Julian | 2015-12-06 19:10:38 -0400 |
commit | 31b986e80335bf262997b97e3d22486a7b91cc4b (patch) | |
tree | f4f66249fa51a3b859fcea67f546291fed6d8022 | |
parent | 2c392029d19aee4962f3b37b4f10eb79f7c01e3f (diff) |
- Better handling generics when analysing class methods.
-rw-r--r-- | src/lux/analyser/host.clj | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/src/lux/analyser/host.clj b/src/lux/analyser/host.clj index b4d862be2..a119ba981 100644 --- a/src/lux/analyser/host.clj +++ b/src/lux/analyser/host.clj @@ -496,11 +496,13 @@ "[Ljava.lang.Object;") )) -(defn generic-class->type [gclass] - "(-> GenericClass (Lux Type))" +(defn generic-class->type [env gclass] + "(-> (List (, TypeVar Type)) GenericClass (Lux Type))" (|case gclass (&/$GenericTypeVar var-name) - (return (&type/Data$ "java.lang.Object" &/Nil$)) + (if-let [ex (&/|get var-name env)] + (return ex) + (fail (str "[Analysis Error] Unknown type var: " var-name))) (&/$GenericClass name params) (case name @@ -514,23 +516,28 @@ "char" (return (&type/Data$ "java.lang.Character" (&/|list))) "void" (return &type/Unit) ;; else - (|do [=params (&/map% generic-class->type params)] + (|do [=params (&/map% (partial generic-class->type env) params)] (return (&type/Data$ name =params)))) (&/$GenericArray param) - (|do [=param (generic-class->type param)] + (|do [=param (generic-class->type env param)] (return (&type/Data$ &host-type/array-data-tag (&/|list =param)))) )) (defn ^:private analyse-method [analyse class-decl method] (|do [:let [[?cname ?cparams] class-decl - class-type (&type/Data$ ?cname &/Nil$) + class-type (&/V &/$GenericClass (&/T ?cname &/Nil$)) [?decl ?body] method - [_ _ _ _ _ ?inputs ?output] ?decl] - output-type (generic-class->type ?output) + [_ _ _ ?gvars ?exs ?inputs ?output] ?decl + all-gvars (&/|++ ?cparams ?gvars)] + gvar-env (&/map% (fn [gvar] + (|do [ex &type/existential] + (return (&/T gvar ex)))) + all-gvars) + output-type (generic-class->type gvar-env ?output) =body (&/fold (fn [body* input*] (|do [:let [[iname itype*] input*] - itype (generic-class->type itype*)] + itype (generic-class->type gvar-env itype*)] (&&env/with-local iname itype body*))) (&&/analyse-1 analyse output-type ?body) |