From 7027b09b68a5ad8f7a4eb2f9edd913d43d2f1730 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sat, 14 Sep 2019 23:42:56 -0400 Subject: More fixes. --- documentation/research/text_editor & ide.md | 1 + new-luxc/project.clj | 5 +- new-luxc/source/luxc/lang/translation/jvm.lux | 6 +- new-luxc/source/luxc/lang/translation/jvm/case.lux | 14 +- .../source/luxc/lang/translation/jvm/function.lux | 11 +- .../luxc/lang/translation/jvm/procedure/common.lux | 7 +- .../source/luxc/lang/translation/jvm/runtime.lux | 26 +- .../source/luxc/lang/translation/jvm/structure.lux | 2 +- new-luxc/source/program.lux | 5 +- stdlib/source/lux/control/parser/text.lux | 27 +- stdlib/source/lux/data/text.lux | 2 +- stdlib/source/lux/host.jvm.lux | 935 +++++++++++---------- stdlib/source/lux/math.lux | 4 +- stdlib/source/lux/target/jvm/type.lux | 16 +- stdlib/source/lux/target/jvm/type/category.lux | 2 + stdlib/source/lux/target/jvm/type/descriptor.lux | 10 +- stdlib/source/lux/target/jvm/type/parser.lux | 19 +- stdlib/source/lux/target/jvm/type/reflection.lux | 50 +- stdlib/source/lux/target/jvm/type/signature.lux | 10 +- .../tool/compiler/phase/extension/analysis/jvm.lux | 187 +++-- 20 files changed, 766 insertions(+), 573 deletions(-) diff --git a/documentation/research/text_editor & ide.md b/documentation/research/text_editor & ide.md index af0b30091..0a3210eeb 100644 --- a/documentation/research/text_editor & ide.md +++ b/documentation/research/text_editor & ide.md @@ -132,6 +132,7 @@ ## General +1. [The Whole Code Catalog](https://futureofcoding.org/catalog/) 1. http://substance.io/ 1. https://www.querystorm.com/ 1. http://recursivedrawing.com/ diff --git a/new-luxc/project.clj b/new-luxc/project.clj index cd74becbc..2b0bbe90c 100644 --- a/new-luxc/project.clj +++ b/new-luxc/project.clj @@ -1,7 +1,8 @@ (def version "0.6.0-SNAPSHOT") (def repo "https://github.com/LuxLang/lux") -(def sonatype-releases "https://oss.sonatype.org/service/local/staging/deploy/maven2/") -(def sonatype-snapshots "https://oss.sonatype.org/content/repositories/snapshots/") +(def sonatype "https://oss.sonatype.org") +(def sonatype-releases (str sonatype "/service/local/staging/deploy/maven2/")) +(def sonatype-snapshots (str sonatype "/content/repositories/snapshots/")) (defproject com.github.luxlang/new-luxc #=(identity version) :description "A re-written compiler for Lux." diff --git a/new-luxc/source/luxc/lang/translation/jvm.lux b/new-luxc/source/luxc/lang/translation/jvm.lux index 86d7f9b9a..fccbd14bf 100644 --- a/new-luxc/source/luxc/lang/translation/jvm.lux +++ b/new-luxc/source/luxc/lang/translation/jvm.lux @@ -148,9 +148,7 @@ (def: define! (..define! library loader))))))) -(def: #export runtime-class "LuxRuntime") -(def: #export function-class "LuxFunction") - (def: #export $Variant (type.array ..$Value)) (def: #export $Tuple (type.array ..$Value)) -(def: #export $Function (type.class ..function-class (list))) +(def: #export $Function (type.class "LuxFunction" (list))) +(def: #export $Runtime (type.class "LuxRuntime" (list))) diff --git a/new-luxc/source/luxc/lang/translation/jvm/case.lux b/new-luxc/source/luxc/lang/translation/jvm/case.lux index c157a5776..484604323 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/case.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/case.lux @@ -26,8 +26,6 @@ ["." // ["." runtime]]) -(def: $Runtime (type.class //.runtime-class (list))) - (def: (pop-altI stack-depth) (-> Nat Inst) (.case stack-depth @@ -45,7 +43,7 @@ (def: pushI Inst - (|>> (_.INVOKESTATIC $Runtime "pm_push" (type.method [(list runtime.$Stack //.$Value) runtime.$Stack (list)])))) + (|>> (_.INVOKESTATIC //.$Runtime "pm_push" (type.method [(list runtime.$Stack //.$Value) runtime.$Stack (list)])))) (def: (path' phase stack-depth @else @end path) (-> Phase Nat Label Label Path (Operation Inst)) @@ -100,7 +98,7 @@ (_.CHECKCAST //.$Variant) (_.int (.int ( idx))) - (_.INVOKESTATIC $Runtime "pm_variant" (type.method [(list //.$Variant runtime.$Tag runtime.$Flag) runtime.$Value (list)])) + (_.INVOKESTATIC //.$Runtime "pm_variant" (type.method [(list //.$Variant runtime.$Tag runtime.$Flag) runtime.$Value (list)])) _.DUP (_.IFNULL @fail) (_.GOTO @success) @@ -118,7 +116,7 @@ _.AALOAD lefts - (_.INVOKESTATIC $Runtime "tuple_left" (type.method [(list //.$Tuple runtime.$Index) //.$Value (list)])))] + (_.INVOKESTATIC //.$Runtime "tuple_left" (type.method [(list //.$Tuple runtime.$Index) //.$Value (list)])))] (|>> peekI (_.CHECKCAST //.$Tuple) (_.int (.int lefts)) @@ -129,7 +127,7 @@ (operation@wrap (|>> peekI (_.CHECKCAST //.$Tuple) (_.int (.int lefts)) - (_.INVOKESTATIC $Runtime "tuple_right" (type.method [(list //.$Tuple runtime.$Index) //.$Value (list)])) + (_.INVOKESTATIC //.$Runtime "tuple_right" (type.method [(list //.$Tuple runtime.$Index) //.$Value (list)])) pushI)) ## Extra optimization @@ -155,7 +153,7 @@ (wrap (|>> peekI (_.CHECKCAST //.$Tuple) (_.int (.int lefts)) - (_.INVOKESTATIC $Runtime (type.method [(list //.$Tuple runtime.$Index) //.$Value (list)])) + (_.INVOKESTATIC //.$Runtime (type.method [(list //.$Tuple runtime.$Index) //.$Value (list)])) (_.ASTORE register) then!)))) ([synthesis.member/left "tuple_left"] @@ -188,7 +186,7 @@ (wrap (|>> pathI (_.label @else) _.POP - (_.INVOKESTATIC $Runtime "pm_fail" (type.method [(list) type.void (list)])) + (_.INVOKESTATIC //.$Runtime "pm_fail" (type.method [(list) type.void (list)])) _.NULL (_.GOTO @end))))) diff --git a/new-luxc/source/luxc/lang/translation/jvm/function.lux b/new-luxc/source/luxc/lang/translation/jvm/function.lux index 56ef21b46..d95c2c6c0 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/function.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/function.lux @@ -258,15 +258,16 @@ (_.INVOKESPECIAL class "" (init-method env function-arity)) _.ARETURN)) )))) - _.fuse)] + _.fuse) + failureI (|>> (_.INVOKESTATIC //.$Runtime "apply_fail" (type.method [(list) type.void (list)])) + _.NULL + _.ARETURN)] (def.method #$.Public $.noneM runtime.apply-method (runtime.apply-signature apply-arity) (|>> get-amount-of-partialsI (_.TABLESWITCH +0 (|> num-partials dec .int) @default @labels) casesI - (_.INVOKESTATIC runtime.$Runtime "apply_fail" (type.method [(list) type.void (list)])) - _.NULL - _.ARETURN + failureI )))) (def: #export (with-function @begin class env arity bodyI) @@ -309,7 +310,7 @@ [function-class (def.class #$.V1_6 #$.Public $.finalC function-class (list) - ($.simple-class //.function-class) (list) + //.$Function (list) functionD)])] (wrap instanceI))) diff --git a/new-luxc/source/luxc/lang/translation/jvm/procedure/common.lux b/new-luxc/source/luxc/lang/translation/jvm/procedure/common.lux index 9ed40a99a..a46813232 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/procedure/common.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/procedure/common.lux @@ -16,7 +16,8 @@ ["." dictionary]]] [target [jvm - ["." type]]] + ["." type + ["." signature]]]] [tool [compiler ["." synthesis (#+ Synthesis %synthesis)] @@ -128,7 +129,7 @@ (Unary Inst) (|>> riskyI (_.CHECKCAST ///.$Function) - (_.INVOKESTATIC runtime.$Runtime "try" (type.method [(list ///.$Function) ///.$Variant (list)])))) + (_.INVOKESTATIC ///.$Runtime "try" runtime.try))) (template [ ] [(def: ( [maskI inputI]) @@ -216,7 +217,7 @@ [f64::encode (_.unwrap type.double) (_.INVOKESTATIC (type.class "java.lang.Double" (list)) "toString" (type.method [(list type.double) $String (list)]))] [f64::decode ..check-stringI - (_.INVOKESTATIC runtime.$Runtime "decode_frac" (type.method [(list $String) ///.$Variant (list)]))] + (_.INVOKESTATIC ///.$Runtime "decode_frac" (type.method [(list $String) ///.$Variant (list)]))] ) (def: (text::size inputI) diff --git a/new-luxc/source/luxc/lang/translation/jvm/runtime.lux b/new-luxc/source/luxc/lang/translation/jvm/runtime.lux index 11f8870eb..d616d62e9 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/runtime.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/runtime.lux @@ -11,7 +11,8 @@ ["." type (#+ Type) ["." category (#+ Void Value Return Primitive Object Class Array Var Parameter Method)] ["." descriptor (#+ Descriptor)] - ["." signature (#+ Signature)]]]] + ["." signature (#+ Signature)] + ["." reflection]]]] [tool [compiler [arity (#+ Arity)] @@ -33,7 +34,6 @@ (def: #export $Index type.int) (def: #export $Stack (type.array $Value)) (def: $Throwable (type.class "java.lang.Throwable" (list))) -(def: #export $Runtime (type.class "java.lang.Runtime" (list))) (def: nullary-init-methodT (type.method [(list) type.void (list)])) @@ -55,7 +55,7 @@ (def: #export variantI Inst - (_.INVOKESTATIC (type.class //.runtime-class (list)) "variant_make" variant-method)) + (_.INVOKESTATIC //.$Runtime "variant_make" variant-method)) (def: #export leftI Inst @@ -82,7 +82,7 @@ (_.string synthesis.unit) variantI)) -(def: (try-methodI unsafeI) +(def: (tryI unsafeI) (-> Inst Inst) (<| _.with-label (function (_ @from)) _.with-label (function (_ @to)) @@ -128,7 +128,7 @@ (def: frac-methods Def (|>> ($d.method #$.Public $.staticM "decode_frac" (type.method [(list $Text) //.$Variant (list)]) - (try-methodI + (tryI (|>> (_.ALOAD 0) (_.INVOKESTATIC (type.class "java.lang.Double" (list)) "parseDouble" (type.method [(list $Text) type.double (list)])) (_.wrap type.double)))) @@ -280,6 +280,8 @@ ))) ))) +(def: #export try (type.method [(list //.$Function) //.$Variant (list)])) + (def: io-methods Def (let [StringWriter (type.class "java.io.StringWriter" (list)) @@ -295,7 +297,7 @@ (_.boolean true) (_.INVOKESPECIAL PrintWriter "" (type.method [(list (type.class "java.io.Writer" (list)) type.boolean) type.void (list)])) )] - (|>> ($d.method #$.Public $.staticM "try" (type.method [(list //.$Function) //.$Variant (list)]) + (|>> ($d.method #$.Public $.staticM "try" ..try (<| _.with-label (function (_ @from)) _.with-label (function (_ @to)) _.with-label (function (_ @handler)) @@ -317,15 +319,18 @@ _.ARETURN))) ))) +(def: reflection (|>> type.reflection reflection.reflection)) + (def: translate-runtime (Operation ByteCode) - (let [bytecode ($d.class #$.V1_6 #$.Public $.finalC //.runtime-class (list) (type.class "java.lang.Object" (list)) (list) + (let [runtime-class (..reflection //.$Runtime) + bytecode ($d.class #$.V1_6 #$.Public $.finalC runtime-class (list) (type.class "java.lang.Object" (list)) (list) (|>> adt-methods frac-methods pm-methods io-methods))] (do phase.monad - [_ (generation.execute! //.runtime-class [//.runtime-class bytecode])] + [_ (generation.execute! runtime-class [runtime-class bytecode])] (wrap bytecode)))) (def: translate-function @@ -345,7 +350,8 @@ (list& ($d.abstract-method #$.Public $.noneM apply-method (apply-signature 1))) $d.fuse) $Object (type.class "java.lang.Object" (list)) - bytecode ($d.abstract #$.V1_6 #$.Public $.noneC //.function-class (list) $Object (list) + function-class (..reflection //.$Function) + bytecode ($d.abstract #$.V1_6 #$.Public $.noneC function-class (list) $Object (list) (|>> ($d.field #$.Public $.finalF partials-field type.int) ($d.method #$.Public $.noneM "" (type.method [(list type.int) type.void (list)]) (|>> (_.ALOAD 0) @@ -356,7 +362,7 @@ _.RETURN)) applyI))] (do phase.monad - [_ (generation.execute! //.function-class [//.function-class bytecode])] + [_ (generation.execute! function-class [function-class bytecode])] (wrap bytecode)))) (def: #export translate diff --git a/new-luxc/source/luxc/lang/translation/jvm/structure.lux b/new-luxc/source/luxc/lang/translation/jvm/structure.lux index f7e66a75a..10c9bacb9 100644 --- a/new-luxc/source/luxc/lang/translation/jvm/structure.lux +++ b/new-luxc/source/luxc/lang/translation/jvm/structure.lux @@ -68,7 +68,7 @@ lefts))) (flagI right?) memberI - (_.INVOKESTATIC (type.class //.runtime-class (list)) + (_.INVOKESTATIC //.$Runtime "variant_make" (type.method [(list //runtime.$Tag //runtime.$Flag //runtime.$Value) //.$Variant diff --git a/new-luxc/source/program.lux b/new-luxc/source/program.lux index 43cc9e9cd..b579b0df0 100644 --- a/new-luxc/source/program.lux +++ b/new-luxc/source/program.lux @@ -136,10 +136,9 @@ ($i.label @end) $i.POP ($i.ASTORE 0))) - $Function ($t.class jvm.function-class (list)) - run-ioI (|>> ($i.CHECKCAST $Function) + run-ioI (|>> ($i.CHECKCAST jvm.$Function) $i.NULL - ($i.INVOKEVIRTUAL $Function runtime.apply-method (runtime.apply-signature 1))) + ($i.INVOKEVIRTUAL jvm.$Function runtime.apply-method (runtime.apply-signature 1))) main-type ($t.method [(list ($t.array ($t.class "java.lang.String" (list)))) $t.void (list)]) diff --git a/stdlib/source/lux/control/parser/text.lux b/stdlib/source/lux/control/parser/text.lux index 44d568eaf..5a7c2bb10 100644 --- a/stdlib/source/lux/control/parser/text.lux +++ b/stdlib/source/lux/control/parser/text.lux @@ -109,19 +109,20 @@ [not! Slice ..any!] ) -(def: #export (this reference) - {#.doc "Lex a text if it matches the given sample."} - (-> Text (Parser Any)) - (function (_ [offset tape]) - (case (/.index-of' reference offset tape) - (#.Some where) - (if (n.= offset where) - (#try.Success [[("lux i64 +" (/.size reference) offset) tape] - []]) - (#try.Failure ($_ /@compose "Could not match: " (/.encode reference) " @ " (maybe.assume (/.clip' offset tape))))) - - _ - (#try.Failure ($_ /@compose "Could not match: " (/.encode reference)))))) +(with-expansions [ (as-is (#try.Failure ($_ /@compose "Could not match: " (/.encode reference) " @ " (maybe.assume (/.clip' offset tape)))))] + (def: #export (this reference) + {#.doc "Lex a text if it matches the given sample."} + (-> Text (Parser Any)) + (function (_ [offset tape]) + (case (/.index-of' reference offset tape) + (#.Some where) + (if (n.= offset where) + (#try.Success [[("lux i64 +" (/.size reference) offset) tape] + []]) + ) + + _ + )))) (def: #export (this? reference) {#.doc "Lex a text if it matches the given sample."} diff --git a/stdlib/source/lux/data/text.lux b/stdlib/source/lux/data/text.lux index dce88022b..99cf151b1 100644 --- a/stdlib/source/lux/data/text.lux +++ b/stdlib/source/lux/data/text.lux @@ -198,7 +198,7 @@ (~~ (static @.jvm)) (|> input (:coerce (primitive "java.lang.String")) - ("jvm member invoke virtual" "java.lang.String" "hashCode") + ("jvm member invoke virtual" [] "java.lang.String" "hashCode" []) "jvm conversion int-to-long" "jvm object cast" (: (primitive "java.lang.Long")) diff --git a/stdlib/source/lux/host.jvm.lux b/stdlib/source/lux/host.jvm.lux index 69a156504..c668431c8 100644 --- a/stdlib/source/lux/host.jvm.lux +++ b/stdlib/source/lux/host.jvm.lux @@ -8,7 +8,9 @@ ["." function] ["." io] ["." try (#+ Try)] + ["." exception (#+ Exception exception:)] ["<>" parser ("#@." monad) + ["" text] ["" code (#+ Parser)]]] [data ["." maybe] @@ -30,13 +32,17 @@ [encoding ["." name (#+ External)]] ["." type (#+ Type Argument Typed) - ["." category (#+ Void Value Return Method Primitive Object Class Array Var Parameter)] + ["." category (#+ Void Value Return Method Primitive Object Class Array Var Parameter Declaration)] ["." box] + ["." descriptor] ["." signature] ["." reflection] ["." parser]]]]]) -(type: Variable Text) +(def: internal + (-> External Text) + (|>> name.internal + name.read)) (def: signature (|>> type.signature signature.signature)) (def: reflection (|>> type.reflection reflection.reflection)) @@ -176,19 +182,15 @@ #Class #Interface) -(type: Class-Declaration - {#class-name Text - #class-params (List (Type Var))}) - (type: StackFrame (primitive "java/lang/StackTraceElement")) (type: StackTrace (array.Array StackFrame)) -(type: AnnotationParam +(type: Annotation-Parameter [Text Code]) (type: Annotation {#ann-name Text - #ann-params (List AnnotationParam)}) + #ann-params (List Annotation-Parameter)}) (type: Member-Declaration {#member-name Text @@ -196,53 +198,53 @@ #member-anns (List Annotation)}) (type: FieldDecl - (#ConstantField Type Code) - (#VariableField StateModifier Type)) + (#ConstantField (Type Value) Code) + (#VariableField StateModifier (Type Value))) (type: MethodDecl - {#method-tvars (List Variable) - #method-inputs (List Type) - #method-output Return - #method-exs (List Class)}) + {#method-tvars (List (Type Var)) + #method-inputs (List (Type Value)) + #method-output (Type Return) + #method-exs (List (Type Class))}) (type: Method-Definition (#ConstructorMethod [Bit - (List Variable) + (List (Type Var)) Text (List Argument) (List (Typed Code)) Code - (List Class)]) + (List (Type Class))]) (#VirtualMethod [Bit Bit - (List Variable) + (List (Type Var)) Text (List Argument) - Return + (Type Return) Code - (List Class)]) + (List (Type Class))]) (#OverridenMethod [Bit - Class-Declaration - (List Variable) + (Type Declaration) + (List (Type Var)) Text (List Argument) - Return + (Type Return) Code - (List Class)]) + (List (Type Class))]) (#StaticMethod [Bit - (List Variable) + (List (Type Var)) (List Argument) - Return + (Type Return) Code - (List Class)]) - (#AbstractMethod [(List Variable) + (List (Type Class))]) + (#AbstractMethod [(List (Type Var)) (List Argument) - Return - (List Class)]) - (#NativeMethod [(List Variable) + (Type Return) + (List (Type Class))]) + (#NativeMethod [(List (Type Var)) (List Argument) - Return - (List Class)])) + (Type Return) + (List (Type Class))])) (type: Partial-Call {#pc-method Name @@ -256,8 +258,8 @@ {#import-member-mode Primitive-Mode #import-member-alias Text #import-member-kind ImportMethodKind - #import-member-tvars (List Variable) - #import-member-args (List [Bit Type]) + #import-member-tvars (List (Type Var)) + #import-member-args (List [Bit (Type Value)]) #import-member-maybe? Bit #import-member-try? Bit #import-member-io? Bit}) @@ -267,7 +269,7 @@ (type: ImportMethodDecl {#import-method-name Text - #import-method-return Return}) + #import-method-return (Type Return)}) (type: ImportFieldDecl {#import-field-mode Primitive-Mode @@ -275,7 +277,7 @@ #import-field-static? Bit #import-field-maybe? Bit #import-field-setter? Bit - #import-field-type Type}) + #import-field-type (Type Value)}) (type: Import-Member-Declaration (#EnumDecl (List Text)) @@ -283,7 +285,7 @@ (#MethodDecl [ImportMethodCommons ImportMethodDecl]) (#FieldAccessDecl ImportFieldDecl)) -(type: Class-Imports +(type: Context (List [Text Text])) (def: (short-class-name name) @@ -340,9 +342,9 @@ #.None)] [parser.var? name (code.identifier ["" name])] - [parser.wildcard? bound (` .Any)] - [parser.lower? bound (` .Any)] - [parser.upper? bound (parameter-type bound)] + [parser.wildcard? _ (` .Any)] + [parser.lower? _ (` .Any)] + [parser.upper? limit (parameter-type limit)] [parser.class? [name parameters] (` (.primitive (~ (code.text name)) [(~+ (list@map parameter-type parameters))]))])) @@ -371,33 +373,32 @@ (undefined) ))) -(def: (declaration-type$ (^slots [#class-name #class-params])) - (-> Class-Declaration Code) - (` (primitive (~ (code.text class-name)) - [(~+ (list@map code.local-identifier class-params))]))) +(def: declaration-type$ + (-> (Type Declaration) Code) + (|>> ..signature code.text)) -(def: empty-imports - Class-Imports +(def: fresh + Context (list)) (def: (get-import name imports) - (-> Text Class-Imports (Maybe Text)) + (-> Text Context (Maybe Text)) (:: maybe.functor map product.right (list.find (|>> product.left (text@= name)) imports))) (def: (add-import short+full imports) - (-> [Text Text] Class-Imports Class-Imports) + (-> [Text Text] Context Context) (#.Cons short+full imports)) -(def: (class-imports compiler) - (-> Lux Class-Imports) +(def: (context compiler) + (-> Lux Context) (case (macro.run compiler - (: (Meta Class-Imports) + (: (Meta Context) (do macro.monad [current-module macro.current-module-name definitions (macro.definitions current-module)] - (wrap (list@fold (: (-> [Text Global] Class-Imports Class-Imports) + (wrap (list@fold (: (-> [Text Global] Context Context) (function (_ [short-name constant] imports) (case constant (#.Left _) @@ -410,13 +411,13 @@ _ imports)))) - empty-imports + ..fresh definitions))))) (#.Left _) (list) (#.Right imports) imports)) (def: (qualify imports name) - (-> Class-Imports Text Text) + (-> Context Text Text) (|> imports (get-import name) (maybe.default name))) (def: (make-get-const-parser class-name field-name) @@ -480,8 +481,8 @@ (make-put-var-parser class-name field-name)))) (def: (decorate-input [class value]) - (-> [Text Code] Code) - (` [(~ (code.text class)) (~ value)])) + (-> [(Type Value) Code] Code) + (` [(~ (code.text (..signature class))) (~ value)])) (def: (make-constructor-parser class-name arguments) (-> Text (List Argument) (Parser Code)) @@ -491,7 +492,7 @@ (.tuple (<>.exactly (list.size arguments) .any)))))] (wrap (` ("jvm member invoke constructor" (~ (code.text class-name)) (~+ (|> args - (list.zip2 (list@map (|>> product.right ..signature) arguments)) + (list.zip2 (list@map product.right arguments)) (list@map ..decorate-input)))))))) (def: (make-static-method-parser class-name method-name arguments) @@ -503,7 +504,7 @@ (.tuple (<>.exactly (list.size arguments) .any)))))] (wrap (` ("jvm member invoke static" (~ (code.text class-name)) (~ (code.text method-name)) (~+ (|> args - (list.zip2 (list@map (|>> product.right ..signature) arguments)) + (list.zip2 (list@map product.right arguments)) (list@map ..decorate-input)))))))) (template [ ] @@ -517,7 +518,7 @@ (wrap (` ( (~ (code.text class-name)) (~ (code.text method-name)) (~' _jvm_this) (~+ (|> args - (list.zip2 (list@map (|>> product.right ..signature) arguments)) + (list.zip2 (list@map product.right arguments)) (list@map ..decorate-input))))))))] [make-special-method-parser "jvm member invoke special"] @@ -544,7 +545,7 @@ (make-virtual-method-parser class-name method-name args))) (def: (full-class-name^ imports) - (-> Class-Imports (Parser Text)) + (-> Context (Parser Text)) (do <>.monad [name .local-identifier] (wrap (qualify imports name)))) @@ -566,24 +567,41 @@ (.this! (' #abstract)) (wrap [])))) +(exception: #export (class-names-cannot-contain-periods {name Text}) + (exception.report + ["Name" (%.text name)])) + +(exception: #export (class-name-cannot-be-a-type-variable {name Text} + {type-vars (List (Type Var))}) + (exception.report + ["Name" (%.text name)] + ["Type Variables" (exception.enumerate parser.name type-vars)])) + +(def: (assert exception payload test) + (All [e] (-> (Exception e) e Bit (Parser Any))) + (<>.assert (exception.construct exception payload) + test)) + (def: (assert-valid-class-name type-vars name) - (-> (List Variable) Text (Parser Any)) + (-> (List (Type Var)) External (Parser Any)) (do <>.monad - [_ (<>.assert "Names in class declarations cannot contain periods." - (not (text.contains? name.external-separator name)))] - (<>.assert (format name " cannot be a type-var!") - (not (list.member? text.equivalence type-vars name))))) + [_ (..assert ..class-names-cannot-contain-periods [name] + (not (text.contains? name.external-separator name)))] + (..assert ..class-name-cannot-be-a-type-variable [name type-vars] + (not (list.member? text.equivalence + (list@map parser.name type-vars) + name))))) (def: (valid-class-name imports type-vars) - (-> Class-Imports (List Variable) (Parser Text)) + (-> Context (List (Type Var)) (Parser External)) (do <>.monad [name (full-class-name^ imports) _ (assert-valid-class-name type-vars name)] (wrap name))) (def: (class^' parameter^ imports type-vars) - (-> (-> Class-Imports (List Variable) (Parser (Type Parameter))) - (-> Class-Imports (List Variable) (Parser (Type Class)))) + (-> (-> Context (List (Type Var)) (Parser (Type Parameter))) + (-> Context (List (Type Var)) (Parser (Type Class)))) (do <>.monad [[name parameters] (: (Parser [External (List (Type Parameter))]) ($_ <>.either @@ -593,12 +611,18 @@ (<>.some (parameter^ imports type-vars))))))] (wrap (type.class name parameters)))) +(exception: #export (unexpected-type-variable {name Text} + {type-vars (List (Type Var))}) + (exception.report + ["Unexpected Type Variable" (%.text name)] + ["Expected Type Variables" (exception.enumerate parser.name type-vars)])) + (def: (variable^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (Type Parameter))) + (-> Context (List (Type Var)) (Parser (Type Parameter))) (do <>.monad [name (full-class-name^ imports) - _ (<>.assert "Variable name must ne one of the expected type-variables." - (list.member? text.equivalence type-vars name))] + _ (..assert ..unexpected-type-variable [name type-vars] + (list.member? text.equivalence (list@map parser.name type-vars) name))] (wrap (type.var name)))) (def: wildcard^ @@ -620,7 +644,7 @@ ) (def: (parameter^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (Type Parameter))) + (-> Context (List (Type Var)) (Parser (Type Parameter))) (<>.rec (function (_ recur^) (let [class^ (..class^' parameter^ imports type-vars)] @@ -657,7 +681,7 @@ (:: <>.monad map type.array))) (def: (type^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (Type Value))) + (-> Context (List (Type Var)) (Parser (Type Value))) (<>.rec (function (_ type^) ($_ <>.either @@ -667,7 +691,7 @@ )))) (def: (return^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (Type Return))) + (-> Context (List (Type Var)) (Parser (Type Return))) (<>.either (itself^ type.void) (..type^ imports type-vars))) @@ -680,50 +704,53 @@ (.tuple (<>.some var^))) (def: (declaration^ imports) - (-> Class-Imports (Parser Class-Declaration)) - (<>.either (<>.and (valid-class-name imports (list)) - (<>@wrap (list))) - (.form (<>.and (valid-class-name imports (list)) - (<>.some var^))) - )) + (-> Context (Parser (Type Declaration))) + (do <>.monad + [[name variables] (: (Parser [External (List (Type Var))]) + (<>.either (<>.and (valid-class-name imports (list)) + (<>@wrap (list))) + (.form (<>.and (valid-class-name imports (list)) + (<>.some var^))) + ))] + (wrap (type.declaration name variables)))) (def: (class^ imports type-vars) - (-> Class-Imports (List Variable) (Parser Class)) + (-> Context (List (Type Var)) (Parser (Type Class))) (class^' parameter^ imports type-vars)) -(def: annotation-params^ - (Parser (List AnnotationParam)) +(def: annotation-parameters^ + (Parser (List Annotation-Parameter)) (.record (<>.some (<>.and .local-tag .any)))) (def: (annotation^ imports) - (-> Class-Imports (Parser Annotation)) + (-> Context (Parser Annotation)) (<>.either (do <>.monad [ann-name (full-class-name^ imports)] (wrap [ann-name (list)])) (.form (<>.and (full-class-name^ imports) - annotation-params^)))) + annotation-parameters^)))) (def: (annotations^' imports) - (-> Class-Imports (Parser (List Annotation))) + (-> Context (Parser (List Annotation))) (do <>.monad [_ (.this! (' #ann))] (.tuple (<>.some (annotation^ imports))))) (def: (annotations^ imports) - (-> Class-Imports (Parser (List Annotation))) + (-> Context (Parser (List Annotation))) (do <>.monad [anns?? (<>.maybe (annotations^' imports))] (wrap (maybe.default (list) anns??)))) (def: (throws-decl^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (List Class))) + (-> Context (List (Type Var)) (Parser (List (Type Class)))) (<| (<>.default (list)) (do <>.monad [_ (.this! (' #throws))] (.tuple (<>.some (..class^ imports type-vars)))))) (def: (method-decl^ imports type-vars) - (-> Class-Imports (List Variable) (Parser [Member-Declaration MethodDecl])) + (-> Context (List (Type Var)) (Parser [Member-Declaration MethodDecl])) (.form (do <>.monad [tvars (<>.default (list) ..vars^) name .local-identifier @@ -744,7 +771,7 @@ (:: <>.monad wrap []))) (def: (field-decl^ imports type-vars) - (-> Class-Imports (List Variable) (Parser [Member-Declaration FieldDecl])) + (-> Context (List (Type Var)) (Parser [Member-Declaration FieldDecl])) (<>.either (.form (do <>.monad [_ (.this! (' #const)) name .local-identifier @@ -761,24 +788,24 @@ (wrap [[name pm anns] (#VariableField [sm type])]))))) (def: (argument^ imports type-vars) - (-> Class-Imports (List Variable) (Parser Argument)) + (-> Context (List (Type Var)) (Parser Argument)) (.record (<>.and .local-identifier (..type^ imports type-vars)))) (def: (arguments^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (List Argument))) + (-> Context (List (Type Var)) (Parser (List Argument))) (<>.some (argument^ imports type-vars))) (def: (constructor-arg^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (Typed Code))) + (-> Context (List (Type Var)) (Parser (Typed Code))) (.record (<>.and (..type^ imports type-vars) .any))) (def: (constructor-args^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (List (Typed Code)))) + (-> Context (List (Type Var)) (Parser (List (Typed Code)))) (.tuple (<>.some (constructor-arg^ imports type-vars)))) (def: (constructor-method^ imports class-vars) - (-> Class-Imports (List Variable) (Parser [Member-Declaration Method-Definition])) + (-> Context (List (Type Var)) (Parser [Member-Declaration Method-Definition])) (.form (do <>.monad [pm privacy-modifier^ strict-fp? (<>.parses? (.this! (' #strict))) @@ -798,7 +825,7 @@ (#ConstructorMethod strict-fp? method-vars self-name arguments constructor-args body exs)])))) (def: (virtual-method-def^ imports class-vars) - (-> Class-Imports (List Variable) (Parser [Member-Declaration Method-Definition])) + (-> Context (List (Type Var)) (Parser [Member-Declaration Method-Definition])) (.form (do <>.monad [pm privacy-modifier^ strict-fp? (<>.parses? (.this! (' #strict))) @@ -819,12 +846,13 @@ (#VirtualMethod final? strict-fp? method-vars self-name arguments return-type body exs)])))) (def: (overriden-method-def^ imports) - (-> Class-Imports (Parser [Member-Declaration Method-Definition])) + (-> Context (Parser [Member-Declaration Method-Definition])) (.form (do <>.monad [strict-fp? (<>.parses? (.this! (' #strict))) owner-class (declaration^ imports) method-vars (<>.default (list) ..vars^) - #let [total-vars (list@compose (product.right owner-class) method-vars)] + #let [total-vars (list@compose (product.right (parser.declaration owner-class)) + method-vars)] [name self-name arguments] (.form ($_ <>.and .local-identifier .local-identifier @@ -839,7 +867,7 @@ (#OverridenMethod strict-fp? owner-class method-vars self-name arguments return-type body exs)])))) (def: (static-method-def^ imports) - (-> Class-Imports (Parser [Member-Declaration Method-Definition])) + (-> Context (Parser [Member-Declaration Method-Definition])) (.form (do <>.monad [pm privacy-modifier^ strict-fp? (<>.parses? (.this! (' #strict))) @@ -858,7 +886,7 @@ (#StaticMethod strict-fp? method-vars arguments return-type body exs)])))) (def: (abstract-method-def^ imports) - (-> Class-Imports (Parser [Member-Declaration Method-Definition])) + (-> Context (Parser [Member-Declaration Method-Definition])) (.form (do <>.monad [pm privacy-modifier^ _ (.this! (' #abstract)) @@ -875,7 +903,7 @@ (#AbstractMethod method-vars arguments return-type exs)])))) (def: (native-method-def^ imports) - (-> Class-Imports (Parser [Member-Declaration Method-Definition])) + (-> Context (Parser [Member-Declaration Method-Definition])) (.form (do <>.monad [pm privacy-modifier^ _ (.this! (' #native)) @@ -892,7 +920,7 @@ (#NativeMethod method-vars arguments return-type exs)])))) (def: (method-def^ imports class-vars) - (-> Class-Imports (List Variable) (Parser [Member-Declaration Method-Definition])) + (-> Context (List (Type Var)) (Parser [Member-Declaration Method-Definition])) ($_ <>.either (constructor-method^ imports class-vars) (virtual-method-def^ imports class-vars) @@ -922,7 +950,7 @@ .local-identifier))) (def: (import-member-args^ imports type-vars) - (-> Class-Imports (List Variable) (Parser (List [Bit Type]))) + (-> Context (List (Type Var)) (Parser (List [Bit (Type Value)]))) (.tuple (<>.some (<>.and (<>.parses? (.tag! ["" "?"])) (..type^ imports type-vars))))) @@ -939,7 +967,7 @@ (.tag! ["" "auto"]))) (def: (import-member-decl^ imports owner-vars) - (-> Class-Imports (List Variable) (Parser Import-Member-Declaration)) + (-> Context (List (Type Var)) (Parser Import-Member-Declaration)) ($_ <>.either (.form (do <>.monad [_ (.this! (' #enum)) @@ -1003,91 +1031,42 @@ (def: (privacy-modifier$ pm) (-> Privacy Code) (case pm - #PublicP (' "public") - #PrivateP (' "private") - #ProtectedP (' "protected") - #DefaultP (' "default"))) + #PublicP (code.text "public") + #PrivateP (code.text "private") + #ProtectedP (code.text "protected") + #DefaultP (code.text "default"))) (def: (inheritance-modifier$ im) (-> InheritanceModifier Code) (case im - #FinalIM (' "final") - #AbstractIM (' "abstract") - #DefaultIM (' "default"))) + #FinalIM (code.text "final") + #AbstractIM (code.text "abstract") + #DefaultIM (code.text "default"))) -(def: (annotation-param$ [name value]) - (-> AnnotationParam Code) +(def: (annotation-parameter$ [name value]) + (-> Annotation-Parameter Code) (` [(~ (code.text name)) (~ value)])) (def: (annotation$ [name params]) (-> Annotation Code) - (` ((~ (code.text name)) (~+ (list@map annotation-param$ params))))) - -(def: (bound$ kind) - (-> Bound Code) - (case kind - #jvm.Lower (code.local-identifier ">") - #jvm.Upper (code.local-identifier "<"))) - -(def: var$ - (-> Variable Code) - code.text) - -(def: (generic$ generic) - (-> Generic Code) - (case generic - (#jvm.Var var) - (var$ var) - - (#jvm.Class name params) - (` ((~ (code.text name)) (~+ (list@map generic$ params)))) - - (#jvm.Wildcard wilcard) - (case wilcard - #.None - (code.local-identifier "?") - - (#.Some [bound bound]) - (` ((~ (..bound$ bound)) (~ (generic$ bound))))))) - -(def: (type$ type) - (-> Type Code) - (case type - (#jvm.Primitive primitive) - (case primitive - #jvm.Boolean (code.local-identifier reflection.boolean) - #jvm.Byte (code.local-identifier reflection.byte) - #jvm.Short (code.local-identifier reflection.short) - #jvm.Int (code.local-identifier reflection.int) - #jvm.Long (code.local-identifier reflection.long) - #jvm.Float (code.local-identifier reflection.float) - #jvm.Double (code.local-identifier reflection.double) - #jvm.Char (code.local-identifier reflection.char)) - - (#jvm.Generic generic) - (generic$ generic) - - (#jvm.Array elementT) - (` [(~ (type$ elementT))]))) - -(def: (return$ return) - (-> Return Code) - (case return - #.None - (code.local-identifier "void") - - (#.Some type) - (type$ type))) + (` ((~ (code.text name)) (~+ (list@map annotation-parameter$ params))))) -(def: (declaration$ (^open ".")) - (-> Class-Declaration Code) - (` ((~ (code.text class-name)) - (~+ (list@map var$ class-params))))) +(template [ ] + [(def: + (-> (Type ) Code) + (|>> ..signature code.text))] + + [var$ Var] + [parameter$ Parameter] + [value$ Value] + [return$ Return] + [declaration$ Declaration] + [class$ Class] + ) -(def: (class$ [name params]) - (-> Class Code) - (` ((~ (code.text name)) - (~+ (list@map generic$ params))))) +(def: var$' + (-> (Type Var) Code) + (|>> ..signature code.local-identifier)) (def: (method-decl$ [[name pm anns] method-decl]) (-> [Member-Declaration MethodDecl] Code) @@ -1096,7 +1075,7 @@ [(~+ (list@map annotation$ anns))] [(~+ (list@map var$ method-tvars))] [(~+ (list@map class$ method-exs))] - [(~+ (list@map type$ method-inputs))] + [(~+ (list@map value$ method-inputs))] (~ (return$ method-output)))))) (def: (state-modifier$ sm) @@ -1112,7 +1091,7 @@ (#ConstantField class value) (` ("constant" (~ (code.text name)) [(~+ (list@map annotation$ anns))] - (~ (type$ class)) + (~ (value$ class)) (~ value) )) @@ -1121,20 +1100,20 @@ (~ (privacy-modifier$ pm)) (~ (state-modifier$ sm)) [(~+ (list@map annotation$ anns))] - (~ (type$ class)) + (~ (value$ class)) )) )) (def: (argument$ [name type]) (-> Argument Code) - (` [(~ (code.text name)) (~ (type$ type))])) + (` [(~ (code.text name)) (~ (value$ type))])) (def: (constructor-arg$ [class term]) (-> (Typed Code) Code) - (` [(~ (type$ class)) (~ term)])) + (` [(~ (value$ class)) (~ term)])) (def: (method-def$ replacer super-class [[name pm anns] method-def]) - (-> (-> Code Code) Class [Member-Declaration Method-Definition] Code) + (-> (-> Code Code) (Type Class) [Member-Declaration Method-Definition] Code) (case method-def (#ConstructorMethod strict-fp? type-vars self-name arguments constructor-args body exs) (` ("init" @@ -1166,14 +1145,13 @@ (#OverridenMethod strict-fp? declaration type-vars self-name arguments return-type body exs) (let [super-replacer (parser->replacer (.form (do <>.monad [_ (.this! (' ::super!)) - args (.tuple (<>.exactly (list.size arguments) .any)) - #let [arguments' (list@map (|>> product.right type.signature) arguments)]] + args (.tuple (<>.exactly (list.size arguments) .any))] (wrap (` ("jvm member invoke special" - (~ (code.text (product.left super-class))) + (~ (code.text (product.left (parser.read-class super-class)))) (~ (code.text name)) (~' _jvm_this) (~+ (|> args - (list.zip2 arguments') + (list.zip2 (list@map product.right arguments)) (list@map ..decorate-input)))))))))] (` ("override" (~ (declaration$ declaration)) @@ -1227,19 +1205,17 @@ (-> Code Partial-Call Code) (` ((~ (code.identifier method)) (~+ args) (~ g!obj)))) -(def: object-class - Class - ["java/lang/Object" (list)]) +(def: $Object + (Type Class) + (type.class "java.lang.Object" (list))) (syntax: #export (class: - {#let [imports (class-imports *compiler*)]} + {#let [imports (..context *compiler*)]} {im inheritance-modifier^} - {declaration (declaration^ imports)} - {#let [full-class-name (product.left declaration) - imports (add-import [(short-class-name full-class-name) full-class-name] - (class-imports *compiler*))]} - {#let [class-vars (product.right declaration)]} - {super (<>.default object-class + {[full-class-name class-vars] (:: @ map parser.declaration (declaration^ imports))} + {#let [imports (add-import [(short-class-name full-class-name) full-class-name] + (..context *compiler*))]} + {super (<>.default $Object (class^ imports class-vars))} {interfaces (<>.default (list) (.tuple (<>.some (class^ imports class-vars))))} @@ -1276,7 +1252,7 @@ "(::new! []) for calling the class's constructor." "(::resolve! container [value]) for calling the 'resolve' method." )} - (do macro.monad + (do @ [current-module macro.current-module-name #let [fully-qualified-class-name (name.qualify current-module full-class-name) field-parsers (list@map (field->parser fully-qualified-class-name) fields) @@ -1285,7 +1261,7 @@ (<>.fail "") (list@compose field-parsers method-parsers)))]] (wrap (list (` ("jvm class" - (~ (declaration$ (update@ #class-name (name.qualify current-module) declaration))) + (~ (declaration$ (type.declaration (name.qualify current-module full-class-name) class-vars))) (~ (class$ super)) [(~+ (list@map class$ interfaces))] (~ (inheritance-modifier$ im)) @@ -1294,12 +1270,10 @@ [(~+ (list@map (method-def$ replacer super) methods))])))))) (syntax: #export (interface: - {#let [imports (class-imports *compiler*)]} - {declaration (declaration^ imports)} - {#let [full-class-name (product.left declaration) - imports (add-import [(short-class-name full-class-name) full-class-name] - (class-imports *compiler*))]} - {#let [class-vars (product.right declaration)]} + {#let [imports (..context *compiler*)]} + {[full-class-name class-vars] (:: @ map parser.declaration (declaration^ imports))} + {#let [imports (add-import [(short-class-name full-class-name) full-class-name] + (..context *compiler*))]} {supers (<>.default (list) (.tuple (<>.some (class^ imports class-vars))))} {annotations (annotations^ imports)} @@ -1307,16 +1281,18 @@ {#.doc (doc "Allows defining JVM interfaces." (interface: TestInterface ([] foo [boolean String] void #throws [Exception])))} - (wrap (list (` ("jvm class interface" - (~ (declaration$ declaration)) - [(~+ (list@map class$ supers))] - [(~+ (list@map annotation$ annotations))] - (~+ (list@map method-decl$ members))))))) + (do @ + [current-module macro.current-module-name] + (wrap (list (` ("jvm class interface" + (~ (declaration$ (type.declaration (name.qualify current-module full-class-name) class-vars))) + [(~+ (list@map class$ supers))] + [(~+ (list@map annotation$ annotations))] + (~+ (list@map method-decl$ members)))))))) (syntax: #export (object - {#let [imports (class-imports *compiler*)]} + {#let [imports (..context *compiler*)]} {class-vars ..vars^} - {super (<>.default object-class + {super (<>.default $Object (class^ imports class-vars))} {interfaces (<>.default (list) (.tuple (<>.some (class^ imports class-vars))))} @@ -1392,7 +1368,7 @@ (wrap (list (` ("lux try" ((~! io.label) (.function ((~ g!_) (~ g!_)) (~ expression))))))))) -(syntax: #export (check {#let [imports (class-imports *compiler*)]} +(syntax: #export (check {#let [imports (..context *compiler*)]} {class (..type^ imports (list))} {unchecked (<>.maybe .any)}) {#.doc (doc "Checks whether an object is an instance of a particular class." @@ -1401,7 +1377,7 @@ (#.Some value-as-string) #.None))} (with-gensyms [g!_ g!unchecked] - (let [class-name (reflection.class class) + (let [class-name (..reflection class) class-type (` (.primitive (~ (code.text class-name)))) check-type (` (.Maybe (~ class-type))) check-code (` (if ("jvm object instance?" (~ (code.text class-name)) (~ g!unchecked)) @@ -1438,21 +1414,22 @@ (exec (~+ (list@map (complete-call$ g!obj) methods)) (~ g!obj)))))))) -(def: (class-import$ long-name? [full-name params]) - (-> Bit Class-Declaration Code) - (let [def-name (if long-name? - full-name - (short-class-name full-name)) - params' (list@map code.local-identifier params)] +(def: (class-import$ long-name? declaration) + (-> Bit (Type Declaration) Code) + (let [[full-name params] (parser.declaration declaration) + def-name (..internal (if long-name? + full-name + (short-class-name full-name))) + params' (list@map ..var$' params)] (` (def: (~ (code.identifier ["" def-name])) - {#..jvm-class (~ (code.text full-name))} + {#..jvm-class (~ (code.text (..internal full-name)))} .Type (All [(~+ params')] (primitive (~ (code.text full-name)) [(~+ params')])))))) (def: (member-type-vars class-tvars member) - (-> (List Variable) Import-Member-Declaration (List Variable)) + (-> (List (Type Var)) Import-Member-Declaration (List (Type Var))) (case member (#ConstructorDecl [commons _]) (list@compose class-tvars (get@ #import-member-tvars commons)) @@ -1468,33 +1445,33 @@ _ class-tvars)) -(def: (member-def-arg-bindings vars class member) - (-> (List Variable) Class-Declaration Import-Member-Declaration (Meta [(List [Bit Code]) (List Text) (List Code)])) +(def: (member-def-arg-bindings vars member) + (-> (List (Type Var)) Import-Member-Declaration (Meta [(List [Bit Code]) (List (Type Value)) (List Code)])) (case member (^or (#ConstructorDecl [commons _]) (#MethodDecl [commons _])) (let [(^slots [#import-member-tvars #import-member-args]) commons] (do macro.monad [arg-inputs (monad.map @ - (: (-> [Bit Type] (Meta [Bit Code])) + (: (-> [Bit (Type Value)] (Meta [Bit Code])) (function (_ [maybe? _]) (with-gensyms [arg-name] (wrap [maybe? arg-name])))) import-member-args) - #let [arg-classes (list@map (|>> product.right type.descriptor) import-member-args) - arg-types (list@map (: (-> [Bit Type] Code) + #let [input-jvm-types (list@map product.right import-member-args) + arg-types (list@map (: (-> [Bit (Type Value)] Code) (function (_ [maybe? arg]) (let [arg-type (value-type (get@ #import-member-mode commons) arg)] (if maybe? (` (Maybe (~ arg-type))) arg-type)))) import-member-args)]] - (wrap [arg-inputs arg-classes arg-types]))) + (wrap [arg-inputs input-jvm-types arg-types]))) _ (:: macro.monad wrap [(list) (list) (list)]))) (def: (decorate-return-maybe member never-null? unboxed return-term) - (-> Import-Member-Declaration Bit Text Code Code) + (-> Import-Member-Declaration Bit (Type Value) Code Code) (case member (^or (#ConstructorDecl [commons _]) (#MethodDecl [commons _])) (cond (or never-null? @@ -1531,49 +1508,33 @@ [decorate-return-io #import-member-io? (` ((~! io.io) (~ return-term)))] ) -(def: var->type-arg - (-> Variable Code) - code.local-identifier) - -(template [ ] - [(def: ) - (def: (type.signature (type.class (list))))] - - ["java.lang.String" string-class string-descriptor] - [box.boolean boolean-box-class boolean-box-descriptor] - [box.byte byte-box-class byte-box-descriptor] - [box.short short-box-class short-box-descriptor] - [box.int int-box-class int-box-descriptor] - [box.long long-box-class long-box-descriptor] - [box.float float-box-class float-box-descriptor] - [box.double double-box-class double-box-descriptor] - [box.char char-box-class char-box-descriptor] - ) +(def: $String (type.class "java.lang.String" (list))) (template [ ] [(def: ( mode [unboxed raw]) - (-> Primitive-Mode [Text Code] Code) - (let [[unboxed refined post] (: [Text Code (List Code)] + (-> Primitive-Mode [(Type Value) Code] Code) + (let [[unboxed refined post] (: [(Type Value) Code (List Code)] (case mode #ManualPrM [unboxed raw (list)] #AutoPrM - (`` (case unboxed - (^template [
 ]
-                                               (^ (static ))
-                                               (with-expansions [' (template.splice )]
-                                                 [
-                                                  (` (.|> (~ raw) (~+ 
)))
-                                                  (list ')]))
-                                             ((~~ (template.splice )))
-                                             
-                                             _
-                                             [unboxed
-                                              (if 
-                                                (` ("jvm object cast" (~ raw)))
-                                                raw)
-                                              (list)]))))
+                                       (with-expansions [' (template.splice )
+                                                          (template [  
 ]
+                                                                        [(:: type.equivalence =  unboxed)
+                                                                         (with-expansions [' (template.splice )]
+                                                                           [
+                                                                            (` (.|> (~ raw) (~+ 
)))
+                                                                            (list ')])]
+
+                                                                        ')]
+                                         (cond 
+                                               ## else
+                                               [unboxed
+                                                (if 
+                                                  (` ("jvm object cast" (~ raw)))
+                                                  raw)
+                                                (list)]))))
            unboxed/boxed (case (dictionary.get unboxed ..boxes)
                            (#.Some boxed)
                            ( unboxed boxed refined)
@@ -1588,29 +1549,29 @@
          (` (.|> (~ unboxed/boxed) (~+ post))))))]
 
   [#1 auto-convert-input ..unbox
-   [[type.boolean-descriptor type.boolean-descriptor (list (` (.: .Bit)) (` (.:coerce (.primitive (~ (code.text box.boolean)))))) []]
-    [type.byte-descriptor type.byte-descriptor (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long))))) (` ..long-to-byte)) []]
-    [type.short-descriptor type.short-descriptor (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long))))) (` ..long-to-short)) []]
-    [type.int-descriptor type.int-descriptor (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long))))) (` ..long-to-int)) []]
-    [type.long-descriptor type.long-descriptor (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long)))))) []]
-    [type.float-descriptor type.float-descriptor (list (` (.: .Frac)) (` (.:coerce (.primitive (~ (code.text box.double))))) (` ..double-to-float)) []]
-    [type.double-descriptor type.double-descriptor (list (` (.: .Frac)) (` (.:coerce (.primitive (~ (code.text box.double)))))) []]
-    [..string-descriptor ..string-descriptor (list (` (.: .Text)) (` (.:coerce (.primitive (~ (code.text ..string-class)))))) []]
-    [..boolean-box-descriptor ..boolean-box-descriptor (list (` (.: .Bit)) (` (.:coerce (.primitive (~ (code.text ..boolean-box-class)))))) []]
-    [..long-box-descriptor ..long-box-descriptor (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text ..long-box-class)))))) []]
-    [..double-box-descriptor ..double-box-descriptor (list (` (.: .Frac)) (` (.:coerce (.primitive (~ (code.text ..double-box-class)))))) []]]]
+   [[type.boolean type.boolean (list (` (.: .Bit)) (` (.:coerce (.primitive (~ (code.text box.boolean)))))) []]
+    [type.byte type.byte (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long))))) (` ..long-to-byte)) []]
+    [type.short type.short (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long))))) (` ..long-to-short)) []]
+    [type.int type.int (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long))))) (` ..long-to-int)) []]
+    [type.long type.long (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long)))))) []]
+    [type.float type.float (list (` (.: .Frac)) (` (.:coerce (.primitive (~ (code.text box.double))))) (` ..double-to-float)) []]
+    [type.double type.double (list (` (.: .Frac)) (` (.:coerce (.primitive (~ (code.text box.double)))))) []]
+    [..$String ..$String (list (` (.: .Text)) (` (.:coerce (.primitive (~ (code.text (..reflection ..$String))))))) []]
+    [(type.class box.boolean (list)) (type.class box.boolean (list)) (list (` (.: .Bit)) (` (.:coerce (.primitive (~ (code.text box.boolean)))))) []]
+    [(type.class box.long (list)) (type.class box.long (list)) (list (` (.: .Int)) (` (.:coerce (.primitive (~ (code.text box.long)))))) []]
+    [(type.class box.double (list)) (type.class box.double (list)) (list (` (.: .Frac)) (` (.:coerce (.primitive (~ (code.text box.double)))))) []]]]
   [#0 auto-convert-output ..box
-   [[type.boolean-descriptor type.boolean-descriptor (list) [(` (.: (.primitive (~ (code.text box.boolean))))) (` (.:coerce .Bit))]]
-    [type.byte-descriptor type.long-descriptor (list (` "jvm conversion byte-to-long")) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
-    [type.short-descriptor type.long-descriptor (list (` "jvm conversion short-to-long")) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
-    [type.int-descriptor type.long-descriptor (list (` "jvm conversion int-to-long")) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
-    [type.long-descriptor type.long-descriptor (list) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
-    [type.float-descriptor type.double-descriptor (list (` "jvm conversion float-to-double")) [(` (.: (.primitive (~ (code.text box.double))))) (` (.:coerce .Frac))]]
-    [type.double-descriptor type.double-descriptor (list) [(` (.: (.primitive (~ (code.text box.double))))) (` (.:coerce .Frac))]]
-    [..string-descriptor ..string-descriptor (list) [(` (.: (.primitive (~ (code.text ..string-class))))) (` (.:coerce .Text))]]
-    [..boolean-box-descriptor ..boolean-box-descriptor (list) [(` (.: (.primitive (~ (code.text ..boolean-box-class))))) (` (.:coerce .Bit))]]
-    [..long-box-descriptor ..long-box-descriptor (list) [(` (.: (.primitive (~ (code.text ..long-box-class))))) (` (.:coerce .Int))]]
-    [..double-box-descriptor ..double-box-descriptor (list) [(` (.: (.primitive (~ (code.text ..double-box-class))))) (` (.:coerce .Frac))]]]]
+   [[type.boolean type.boolean (list) [(` (.: (.primitive (~ (code.text box.boolean))))) (` (.:coerce .Bit))]]
+    [type.byte type.long (list (` "jvm conversion byte-to-long")) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
+    [type.short type.long (list (` "jvm conversion short-to-long")) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
+    [type.int type.long (list (` "jvm conversion int-to-long")) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
+    [type.long type.long (list) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
+    [type.float type.double (list (` "jvm conversion float-to-double")) [(` (.: (.primitive (~ (code.text box.double))))) (` (.:coerce .Frac))]]
+    [type.double type.double (list) [(` (.: (.primitive (~ (code.text box.double))))) (` (.:coerce .Frac))]]
+    [..$String ..$String (list) [(` (.: (.primitive (~ (code.text (..reflection ..$String)))))) (` (.:coerce .Text))]]
+    [(type.class box.boolean (list)) (type.class box.boolean (list)) (list) [(` (.: (.primitive (~ (code.text box.boolean))))) (` (.:coerce .Bit))]]
+    [(type.class box.long (list)) (type.class box.long (list)) (list) [(` (.: (.primitive (~ (code.text box.long))))) (` (.:coerce .Int))]]
+    [(type.class box.double (list)) (type.class box.double (list)) (list) [(` (.: (.primitive (~ (code.text box.double))))) (` (.:coerce .Frac))]]]]
   )
 
 (def: (un-quote quoted)
@@ -1618,7 +1579,7 @@
   (` ((~' ~) (~ quoted))))
 
 (def: (jvm-invoke-inputs mode classes inputs)
-  (-> Primitive-Mode (List Text) (List [Bit Code]) (List Code))
+  (-> Primitive-Mode (List (Type Value)) (List [Bit Code]) (List Code))
   (|> inputs
       (list@map (function (_ [maybe? input])
                   (if maybe?
@@ -1627,14 +1588,9 @@
       (list.zip2 classes)
       (list@map (auto-convert-input mode))))
 
-(def: (with-class-type class expression)
-  (-> Text Code Code)
-  (` (.: (.primitive (~ (code.text class))) (~ expression))))
-
-(def: (member-def-interop vars kind class [arg-function-inputs arg-classes arg-types] member method-prefix)
-  (-> (List Variable) Class-Kind Class-Declaration [(List [Bit Code]) (List Text) (List Code)] Import-Member-Declaration Text (Meta (List Code)))
-  (let [[full-name class-tvars] class
-        all-params (list@map var->type-arg (member-type-vars class-tvars member))]
+(def: (member-def-interop vars kind class [arg-function-inputs input-jvm-types arg-types] member method-prefix)
+  (-> (List (Type Var)) Class-Kind (Type Declaration) [(List [Bit Code]) (List (Type Value)) (List Code)] Import-Member-Declaration Text (Meta (List Code)))
+  (let [[full-name class-tvars] (parser.declaration class)]
     (case member
       (#EnumDecl enum-members)
       (do macro.monad
@@ -1644,7 +1600,7 @@
                               (` (primitive (~ (code.text full-name))))
 
                               _
-                              (let [=class-tvars (list@map var->type-arg class-tvars)]
+                              (let [=class-tvars (list@map ..var$' class-tvars)]
                                 (` (All [(~+ =class-tvars)] (primitive (~ (code.text full-name)) [(~+ =class-tvars)]))))))
                getter-interop (: (-> Text Code)
                                  (function (_ name)
@@ -1656,15 +1612,18 @@
       
       (#ConstructorDecl [commons _])
       (do macro.monad
-        [#let [def-name (code.identifier ["" (format method-prefix member-separator (get@ #import-member-alias commons))])
-               jvm-interop (|> [(type.signature (type.class full-name (list)))
+        [#let [classT (type.class full-name (list))
+               def-name (code.identifier ["" (format method-prefix member-separator (get@ #import-member-alias commons))])
+               jvm-interop (|> [classT
                                 (` ("jvm member invoke constructor"
+                                    [(~+ (list@map ..var$ class-tvars))]
                                     (~ (code.text full-name))
-                                    (~+ (|> (jvm-invoke-inputs (get@ #import-member-mode commons) arg-classes arg-function-inputs)
-                                            (list.zip2 arg-classes)
+                                    [(~+ (list@map ..var$ (get@ #import-member-tvars commons)))]
+                                    (~+ (|> (jvm-invoke-inputs (get@ #import-member-mode commons) input-jvm-types arg-function-inputs)
+                                            (list.zip2 input-jvm-types)
                                             (list@map ..decorate-input)))))]
                                (auto-convert-output (get@ #import-member-mode commons))
-                               (decorate-return-maybe member true full-name)
+                               (decorate-return-maybe member true classT)
                                (decorate-return-try member)
                                (decorate-return-io member))]]
         (wrap (list (` ((~! syntax:) ((~ def-name) (~+ (list@map product.right arg-function-inputs)))
@@ -1692,39 +1651,41 @@
                                             ["jvm member invoke interface"
                                              (list g!obj)]
                                             )))
-                 method-return-class (case (get@ #import-method-return method)
-                                       #.None
-                                       type.void-descriptor
-
-                                       (#.Some return)
-                                       (type.signature return))
-                 jvm-interop (|> [method-return-class
-                                  (` ((~ (code.text jvm-op))
-                                      (~ (code.text full-name))
-                                      (~ (code.text import-method-name))
-                                      (~+ (|> object-ast
-                                              (list@map ..un-quote)
-                                              (list.zip2 (list (type.signature (type.class full-name (list)))))
-                                              (list@map (auto-convert-input (get@ #import-member-mode commons)))))
-                                      (~+ (|> (jvm-invoke-inputs (get@ #import-member-mode commons) arg-classes arg-function-inputs)
-                                              (list.zip2 arg-classes)
-                                              (list@map ..decorate-input)))))]
-                                 (auto-convert-output (get@ #import-member-mode commons))
-                                 (decorate-return-maybe member false method-return-class)
-                                 (decorate-return-try member)
-                                 (decorate-return-io member))]]
+                 method-return (get@ #import-method-return method)
+                 callC (: Code
+                          (` ((~ (code.text jvm-op))
+                              [(~+ (list@map ..var$ class-tvars))]
+                              (~ (code.text full-name))
+                              (~ (code.text import-method-name))
+                              [(~+ (list@map ..var$ (get@ #import-member-tvars commons)))]
+                              (~+ (|> object-ast
+                                      (list@map ..un-quote)
+                                      (list.zip2 (list (type.class full-name (list))))
+                                      (list@map (auto-convert-input (get@ #import-member-mode commons)))))
+                              (~+ (|> (jvm-invoke-inputs (get@ #import-member-mode commons) input-jvm-types arg-function-inputs)
+                                      (list.zip2 input-jvm-types)
+                                      (list@map ..decorate-input))))))
+                 jvm-interop (: Code
+                                (case (type.void? method-return)
+                                  (#.Left method-return)
+                                  (|> [method-return
+                                       callC]
+                                      (auto-convert-output (get@ #import-member-mode commons))
+                                      (decorate-return-maybe member false method-return)
+                                      (decorate-return-try member)
+                                      (decorate-return-io member))
+                                  
+                                  
+                                  (#.Right method-return)
+                                  (|> callC
+                                      (decorate-return-try member)
+                                      (decorate-return-io member))))]]
           (wrap (list (` ((~! syntax:) ((~ def-name) (~+ (list@map product.right arg-function-inputs)) (~+ object-ast))
                           ((~' wrap) (.list (.` (~ jvm-interop))))))))))
 
       (#FieldAccessDecl fad)
       (do macro.monad
         [#let [(^open ".") fad
-               base-gtype (value-type import-field-mode import-field-type)
-               classC (declaration-type$ class)
-               typeC (if import-field-maybe?
-                       (` (Maybe (~ base-gtype)))
-                       base-gtype)
-               tvar-asts (list@map var->type-arg class-tvars)
                getter-name (code.identifier ["" (format method-prefix member-separator import-field-name)])
                setter-name (code.identifier ["" (format method-prefix member-separator import-field-name "!")])]
          getter-interop (with-gensyms [g!obj]
@@ -1732,7 +1693,7 @@
                                               (` ((~ getter-name)))
                                               (` ((~ getter-name) (~ g!obj))))
                                 getter-body (<| (auto-convert-output import-field-mode)
-                                                [(type.signature import-field-type)
+                                                [import-field-type
                                                  (if import-field-static?
                                                    (get-static-field full-name import-field-name)
                                                    (get-virtual-field full-name import-field-name (un-quote g!obj)))])
@@ -1750,7 +1711,7 @@
                                (let [setter-call (if import-field-static?
                                                    (` ((~ setter-name) (~ g!value)))
                                                    (` ((~ setter-name) (~ g!value) (~ g!obj))))
-                                     setter-value (|> [(type.signature import-field-type) (un-quote g!value)]
+                                     setter-value (|> [import-field-type (un-quote g!value)]
                                                       (auto-convert-input import-field-mode))
                                      setter-value (if import-field-maybe?
                                                     (` ((~! !!!) (~ setter-value)))
@@ -1768,48 +1729,50 @@
       )))
 
 (def: (member-import$ vars long-name? kind class member)
-  (-> (List Variable) Bit Class-Kind Class-Declaration Import-Member-Declaration (Meta (List Code)))
-  (let [[full-name _] class
-        method-prefix (if long-name?
-                        full-name
-                        (short-class-name full-name))]
+  (-> (List (Type Var)) Bit Class-Kind (Type Declaration) Import-Member-Declaration (Meta (List Code)))
+  (let [[full-name _] (parser.declaration class)
+        method-prefix (..internal (if long-name?
+                                    full-name
+                                    (short-class-name full-name)))]
     (do macro.monad
-      [=args (member-def-arg-bindings vars class member)]
+      [=args (member-def-arg-bindings vars member)]
       (member-def-interop vars kind class =args member method-prefix))))
 
 (def: interface?
   (All [a] (-> (primitive "java.lang.Class" [a]) Bit))
-  (|>> ("jvm member invoke virtual" "java.lang.Class" "isInterface")
+  (|>> ("jvm member invoke virtual" [] "java.lang.Class" "isInterface" [])
        "jvm object cast"
        (: ..Boolean)
        (:coerce Bit)))
 
 (def: load-class
-  (-> Text (Try (primitive "java.lang.Class" [Any])))
+  (-> External (Try (primitive "java.lang.Class" [Any])))
   (|>> (:coerce (primitive "java.lang.String"))
        ["Ljava/lang/String;"]
-       ("jvm member invoke static" "java.lang.Class" "forName")
-       try))
+       ("jvm member invoke static" [] "java.lang.Class" "forName" [])
+       ..try))
 
-(def: (class-kind [class-name _])
-  (-> Class-Declaration (Meta Class-Kind))
-  (case (load-class class-name)
-    (#.Right class)
-    (:: macro.monad wrap (if (interface? class)
-                           #Interface
-                           #Class))
+(def: (class-kind declaration)
+  (-> (Type Declaration) (Meta Class-Kind))
+  (let [[class-name _] (parser.declaration declaration)]
+    (case (load-class class-name)
+      (#.Right class)
+      (:: macro.monad wrap (if (interface? class)
+                             #Interface
+                             #Class))
 
-    (#.Left _)
-    (macro.fail (format "Unknown class: " class-name))))
+      (#.Left _)
+      (macro.fail (format "Unknown class: " class-name)))))
 
 (syntax: #export (import:
-                   {#let [imports (class-imports *compiler*)]}
+                   {#let [imports (..context *compiler*)]}
                    {long-name? (<>.parses? (.this! (' #long)))}
                    {declaration (declaration^ imports)}
-                   {#let [full-class-name (product.left declaration)
+                   {#let [[full-class-name class-type-vars] (parser.declaration declaration)
+                          full-class-name (..internal full-class-name)
                           imports (add-import [(short-class-name full-class-name) full-class-name]
-                                              (class-imports *compiler*))]}
-                   {members (<>.some (import-member-decl^ imports (product.right declaration)))})
+                                              (..context *compiler*))]}
+                   {members (<>.some (import-member-decl^ imports class-type-vars))})
   {#.doc (doc "Allows importing JVM classes, and using them as types."
               "Their methods, fields and enum options can also be imported."
               "Also, classes which get imported into a module can also be referred-to with their short names in other macros that require JVM classes."
@@ -1858,10 +1821,10 @@
               )}
   (do macro.monad
     [kind (class-kind declaration)
-     =members (monad.map @ (member-import$ (product.right declaration) long-name? kind declaration) members)]
+     =members (monad.map @ (member-import$ class-type-vars long-name? kind declaration) members)]
     (wrap (list& (class-import$ long-name? declaration) (list@join =members)))))
 
-(syntax: #export (array {#let [imports (class-imports *compiler*)]}
+(syntax: #export (array {#let [imports (..context *compiler*)]}
                         {type (..type^ imports (list))}
                         size)
   {#.doc (doc "Create an array of the given type, with the given size."
@@ -1871,44 +1834,116 @@
                        (.:coerce (.primitive (~ (code.text box.long))))
                        "jvm object cast"
                        "jvm conversion long-to-int"))]
-    (case type
-      (^template [ ]
-        (^ (#jvm.Primitive ))
-        (wrap (list (` ( (~ g!size))))))
-      ([#jvm.Boolean "jvm array new boolean"]
-       [#jvm.Byte    "jvm array new byte"]
-       [#jvm.Short   "jvm array new short"]
-       [#jvm.Int     "jvm array new int"]
-       [#jvm.Long    "jvm array new long"]
-       [#jvm.Float   "jvm array new float"]
-       [#jvm.Double  "jvm array new double"]
-       [#jvm.Char    "jvm array new char"])
+    (`` (cond (~~ (template [ ]
+                    [(:: type.equivalence =  type)
+                     (wrap (list (` ( (~ g!size)))))]
+
+                    [type.boolean "jvm array new boolean"]
+                    [type.byte    "jvm array new byte"]
+                    [type.short   "jvm array new short"]
+                    [type.int     "jvm array new int"]
+                    [type.long    "jvm array new long"]
+                    [type.float   "jvm array new float"]
+                    [type.double  "jvm array new double"]
+                    [type.char    "jvm array new char"]))
+              ## else
+              (wrap (list (` (: (~ (value-type #ManualPrM (type.array type)))
+                                ("jvm array new object" (~ g!size))))))))))
+
+(exception: #export (cannot-convert-to-jvm-type {type .Type})
+  (exception.report
+   ["Lux Type" (%.type type)]))
+
+(with-expansions [ (as-is (macro.fail (exception.construct ..cannot-convert-to-jvm-type [type])))]
+  (def: (lux-type->jvm-type type)
+    (-> .Type (Meta (Type Value)))
+    (if (lux-type@= Any type)
+      (:: macro.monad wrap $Object)
+      (case type
+        (#.Primitive name params)
+        (`` (cond (~~ (template []
+                        [(text@= (..reflection ) name)
+                         (case params
+                           #.Nil
+                           (:: macro.monad wrap )
+
+                           _
+                           )]
+                        
+                        [type.boolean]
+                        [type.byte]
+                        [type.short]
+                        [type.int]
+                        [type.long]
+                        [type.float]
+                        [type.double]
+                        [type.char]))
+
+                  (~~ (template []
+                        [(text@= (..reflection (type.array )) name)
+                         (case params
+                           #.Nil
+                           (:: macro.monad wrap (type.array ))
+
+                           _
+                           )]
+                        
+                        [type.boolean]
+                        [type.byte]
+                        [type.short]
+                        [type.int]
+                        [type.long]
+                        [type.float]
+                        [type.double]
+                        [type.char]))
+
+                  (text@= array.type-name name)
+                  (case params
+                    (#.Cons elementLT #.Nil)
+                    (:: macro.monad map type.array
+                        (lux-type->jvm-type elementLT))
+
+                    _
+                    )
+
+                  (text.starts-with? descriptor.array-prefix name)
+                  (case params
+                    #.Nil
+                    (let [[_ unprefixed] (maybe.assume (text.split-with descriptor.array-prefix name))]
+                      (:: macro.monad map type.array
+                          (lux-type->jvm-type (#.Primitive unprefixed (list)))))
+
+                    _
+                    )
+
+                  ## else
+                  (:: macro.monad map (type.class name)
+                      (: (Meta (List (Type Parameter)))
+                         (monad.map macro.monad
+                                    (function (_ paramLT)
+                                      (do macro.monad
+                                        [paramJT (lux-type->jvm-type paramLT)]
+                                        (case (parser.parameter? paramJT)
+                                          (#.Some paramJT)
+                                          (wrap paramJT)
 
-      _
-      (wrap (list (` (: (~ (value-type #ManualPrM (type.array 1 type)))
-                        ("jvm array new object" (~ g!size)))))))))
-
-(def: (type->class-name type)
-  (-> .Type (Meta Text))
-  (if (lux-type@= Any type)
-    (:: macro.monad wrap "java.lang.Object")
-    (case type
-      (#.Primitive name params)
-      (:: macro.monad wrap name)
-
-      (#.Apply A F)
-      (case (lux-type.apply (list A) F)
-        #.None
-        (macro.fail (format "Cannot apply type: " (%.type F) " to " (%.type A)))
+                                          #.None
+                                          )))
+                                    params)))))
 
-        (#.Some type')
-        (type->class-name type'))
-      
-      (#.Named _ type')
-      (type->class-name type')
+        (#.Apply A F)
+        (case (lux-type.apply (list A) F)
+          #.None
+          
 
-      _
-      (macro.fail (format "Cannot convert to JVM type: " (%.type type))))))
+          (#.Some type')
+          (lux-type->jvm-type type'))
+        
+        (#.Named _ type')
+        (lux-type->jvm-type type')
+
+        _
+        ))))
 
 (syntax: #export (array-length array)
   {#.doc (doc "Gives the length of an array."
@@ -1917,17 +1952,24 @@
     [_ (#.Identifier array-name)]
     (do macro.monad
       [array-type (macro.find-type array-name)
-       array-jvm-type (type->class-name array-type)
-       #let [g!extension (code.text (case array-jvm-type
-                                      "[Z" "jvm array length boolean"
-                                      "[B" "jvm array length byte"
-                                      "[S" "jvm array length short"
-                                      "[I" "jvm array length int"
-                                      "[J" "jvm array length long"
-                                      "[F" "jvm array length float"
-                                      "[D" "jvm array length double"
-                                      "[C" "jvm array length char"
-                                      _ "jvm array length object"))]]
+       array-jvm-type (lux-type->jvm-type array-type)
+       #let [g!extension (code.text (`` (cond (~~ (template [ ]
+                                                    [(:: type.equivalence =
+                                                         (type.array )
+                                                         array-jvm-type)
+                                                     ]
+
+                                                    [type.boolean "jvm array length boolean"]
+                                                    [type.byte "jvm array length byte"]
+                                                    [type.short "jvm array length short"]
+                                                    [type.int "jvm array length int"]
+                                                    [type.long "jvm array length long"]
+                                                    [type.float "jvm array length float"]
+                                                    [type.double "jvm array length double"]
+                                                    [type.char "jvm array length char"]))
+                                              
+                                              ## else
+                                              "jvm array length object")))]]
       (wrap (list (` (.|> ((~ g!extension) (~ array))
                           "jvm conversion int-to-long"
                           "jvm object cast"
@@ -1946,29 +1988,31 @@
     [_ (#.Identifier array-name)]
     (do macro.monad
       [array-type (macro.find-type array-name)
-       array-jvm-type (type->class-name array-type)
+       array-jvm-type (lux-type->jvm-type array-type)
        #let [g!idx (` (.|> (~ idx)
                            (.: .Nat)
                            (.:coerce (.primitive (~ (code.text box.long))))
                            "jvm object cast"
                            "jvm conversion long-to-int"))]]
-      (case array-jvm-type
-        (^template [  ]
-          
-          (wrap (list (` (.|> ( (~ g!idx) (~ array))
-                              "jvm object cast"
-                              (.: (.primitive (~ (code.text )))))))))
-        (["[Z" "jvm array read boolean" box.boolean]
-         ["[B" "jvm array read byte" box.byte]
-         ["[S" "jvm array read short" box.short]
-         ["[I" "jvm array read int" box.int]
-         ["[J" "jvm array read long" box.long]
-         ["[F" "jvm array read float" box.float]
-         ["[D" "jvm array read double" box.double]
-         ["[C" "jvm array read char" box.char])
-
-        _
-        (wrap (list (` ("jvm array read object" (~ g!idx) (~ array)))))))
+      (`` (cond (~~ (template [  ]
+                      [(:: type.equivalence =
+                           (type.array )
+                           array-jvm-type)
+                       (wrap (list (` (.|> ( (~ g!idx) (~ array))
+                                           "jvm object cast"
+                                           (.: (.primitive (~ (code.text ))))))))]
+
+                      [type.boolean "jvm array read boolean" box.boolean]
+                      [type.byte "jvm array read byte" box.byte]
+                      [type.short "jvm array read short" box.short]
+                      [type.int "jvm array read int" box.int]
+                      [type.long "jvm array read long" box.long]
+                      [type.float "jvm array read float" box.float]
+                      [type.double "jvm array read double" box.double]
+                      [type.char "jvm array read char" box.char]))
+                
+                ## else
+                (wrap (list (` ("jvm array read object" (~ g!idx) (~ array))))))))
 
     _
     (with-gensyms [g!array]
@@ -1982,41 +2026,42 @@
     [_ (#.Identifier array-name)]
     (do macro.monad
       [array-type (macro.find-type array-name)
-       array-jvm-type (type->class-name array-type)
+       array-jvm-type (lux-type->jvm-type array-type)
        #let [g!idx (` (.|> (~ idx)
                            (.: .Nat)
                            (.:coerce (.primitive (~ (code.text box.long))))
                            "jvm object cast"
                            "jvm conversion long-to-int"))]]
-      (case array-jvm-type
-        (^template [  ]
-          
-          (let [g!value (` (.|> (~ value)
-                                (.:coerce (.primitive (~ (code.text ))))
-                                "jvm object cast"))]
-            (wrap (list (` ( (~ g!idx) (~ g!value) (~ array)))))))
-        (["[Z" "jvm array write boolean" box.boolean]
-         ["[B" "jvm array write byte" box.byte]
-         ["[S" "jvm array write short" box.short]
-         ["[I" "jvm array write int" box.int]
-         ["[J" "jvm array write long" box.long]
-         ["[F" "jvm array write float" box.float]
-         ["[D" "jvm array write double" box.double]
-         ["[C" "jvm array write char" box.char])
-
-        _
-        (wrap (list (` ("jvm array write object" (~ g!idx) (~ value) (~ array)))))))
+      (`` (cond (~~ (template [  ]
+                      [(:: type.equivalence =
+                           (type.array )
+                           array-jvm-type)
+                       (let [g!value (` (.|> (~ value)
+                                             (.:coerce (.primitive (~ (code.text ))))
+                                             "jvm object cast"))]
+                         (wrap (list (` ( (~ g!idx) (~ g!value) (~ array))))))]
+
+                      [type.boolean "jvm array write boolean" box.boolean]
+                      [type.byte "jvm array write byte" box.byte]
+                      [type.short "jvm array write short" box.short]
+                      [type.int "jvm array write int" box.int]
+                      [type.long "jvm array write long" box.long]
+                      [type.float "jvm array write float" box.float]
+                      [type.double "jvm array write double" box.double]
+                      [type.char "jvm array write char" box.char]))
+                
+                ## else
+                (wrap (list (` ("jvm array write object" (~ g!idx) (~ value) (~ array))))))))
 
     _
     (with-gensyms [g!array]
       (wrap (list (` (let [(~ g!array) (~ array)]
                        (..array-write (~ idx) (~ value) (~ g!array)))))))))
 
-(syntax: #export (class-for {#let [imports (class-imports *compiler*)]}
-                            {type (..type^ imports (list))})
+(syntax: #export (class-for {type (..type^ (..context *compiler*) (list))})
   {#.doc (doc "Loads the class as a java.lang.Class object."
               (class-for java/lang/String))}
-  (wrap (list (` ("jvm object class" (~ (code.text (reflection.class type))))))))
+  (wrap (list (` ("jvm object class" (~ (code.text (..reflection type))))))))
 
 (def: get-compiler
   (Meta Lux)
@@ -2028,11 +2073,11 @@
               (resolve "String")
               =>
               "java.lang.String")}
-  (-> Text (Meta Text))
+  (-> External (Meta External))
   (do macro.monad
     [*compiler* get-compiler]
-    (wrap (qualify (class-imports *compiler*) class))))
+    (wrap (qualify (..context *compiler*) class))))
 
-(syntax: #export (type {#let [imports (class-imports *compiler*)]}
+(syntax: #export (type {#let [imports (..context *compiler*)]}
                        {type (..type^ imports (list))})
   (wrap (list (value-type #ManualPrM type))))
diff --git a/stdlib/source/lux/math.lux b/stdlib/source/lux/math.lux
index b030746a0..6f3448f7d 100644
--- a/stdlib/source/lux/math.lux
+++ b/stdlib/source/lux/math.lux
@@ -48,7 +48,7 @@
                       (-> Frac Frac)
                       (|>> !double
                            ["D"]
-                           ("jvm member invoke static" "java.lang.Math" )
+                           ("jvm member invoke static" [] "java.lang.Math"  [])
                            !frac))]
 
                    [cos   "cos"]
@@ -67,7 +67,7 @@
                    )
                  (def: #export (pow param subject)
                    (-> Frac Frac Frac)
-                   (|> ("jvm member invoke static" "java.lang.Math" "pow"
+                   (|> ("jvm member invoke static" [] "java.lang.Math" "pow" []
                         ["D" (!double subject)] ["D" (!double param)])
                        !frac)))
 
diff --git a/stdlib/source/lux/target/jvm/type.lux b/stdlib/source/lux/target/jvm/type.lux
index 890c459b6..e5190429b 100644
--- a/stdlib/source/lux/target/jvm/type.lux
+++ b/stdlib/source/lux/target/jvm/type.lux
@@ -16,7 +16,7 @@
    [encoding
     ["#." name (#+ External)]]]
   ["." / #_
-   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter)]
+   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter Declaration)]
    ["#." signature (#+ Signature)]
    ["#." descriptor (#+ Descriptor)]
    ["#." reflection (#+ Reflection)]])
@@ -78,6 +78,20 @@
       (/descriptor.class name)
       (/reflection.class name)]))
 
+  (def: #export (declaration name variables)
+    (-> External (List (Type Var)) (Type Declaration))
+    (:abstraction
+     [(/signature.declaration name (list@map ..signature variables))
+      (/descriptor.declaration name)
+      (/reflection.declaration name)]))
+
+  (def: #export (as-class type)
+    (-> (Type Declaration) (Type Class))
+    (:abstraction
+     [(/signature.as-class (..signature type))
+      (/descriptor.as-class (..descriptor type))
+      (/reflection.as-class (..reflection type))]))
+
   (def: #export wildcard
     (Type Parameter)
     (:abstraction
diff --git a/stdlib/source/lux/target/jvm/type/category.lux b/stdlib/source/lux/target/jvm/type/category.lux
index cbeaa53ef..f635d3e86 100644
--- a/stdlib/source/lux/target/jvm/type/category.lux
+++ b/stdlib/source/lux/target/jvm/type/category.lux
@@ -31,3 +31,5 @@
   [[Object' Parameter'] Class]
   [[Object'] Array]
   )
+
+(abstract: #export Declaration {} Any)
diff --git a/stdlib/source/lux/target/jvm/type/descriptor.lux b/stdlib/source/lux/target/jvm/type/descriptor.lux
index 367f3338d..53d7eb1b8 100644
--- a/stdlib/source/lux/target/jvm/type/descriptor.lux
+++ b/stdlib/source/lux/target/jvm/type/descriptor.lux
@@ -13,7 +13,7 @@
    [type
     abstract]]
   ["." // #_
-   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter)]
+   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter Declaration)]
    ["/#" // #_
     [encoding
      ["#." name (#+ Internal External)]]]])
@@ -53,6 +53,14 @@
          (text.enclose [..class-prefix ..class-suffix])
          :abstraction))
 
+  (def: #export (declaration name)
+    (-> External (Descriptor Declaration))
+    (:transmutation (..class name)))
+
+  (def: #export as-class
+    (-> (Descriptor Declaration) (Descriptor Class))
+    (|>> :transmutation))
+
   (template [ ]
     [(def: #export 
        (Descriptor )
diff --git a/stdlib/source/lux/target/jvm/type/parser.lux b/stdlib/source/lux/target/jvm/type/parser.lux
index 2ed9b89c5..99f4a57ee 100644
--- a/stdlib/source/lux/target/jvm/type/parser.lux
+++ b/stdlib/source/lux/target/jvm/type/parser.lux
@@ -14,7 +14,7 @@
     [collection
      ["." list]]]]
   ["." // (#+ Type)
-   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter)]
+   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter Declaration)]
    ["#." signature (#+ Signature)]
    ["#." descriptor (#+ Descriptor)]
    ["#." reflection (#+ Reflection)]
@@ -90,7 +90,7 @@
   (<>@map //.var ..var'))
 
 (def: #export var?
-  (-> (Type Parameter) (Maybe Text))
+  (-> (Type Value) (Maybe Text))
   (|>> //.signature
        //signature.signature
        (.run ..var')
@@ -232,3 +232,18 @@
   [parameter? (Type Parameter) ..parameter]
   [object? (Type Object) ..object]
   )
+
+(def: #export declaration
+  (-> (Type Declaration) [External (List (Type Var))])
+  (let [declaration' (: (Parser [External (List (Type Var))])
+                        (|> (<>.and ..class-name
+                                    (|> (<>.some ..var)
+                                        (<>.after (.this //signature.parameters-start))
+                                        (<>.before (.this //signature.parameters-end))
+                                        (<>.default (list))))
+                            (<>.after (.this //descriptor.class-prefix))
+                            (<>.before (.this //descriptor.class-suffix))))]
+    (|>> //.signature
+         //signature.signature
+         (.run declaration')
+         try.assume)))
diff --git a/stdlib/source/lux/target/jvm/type/reflection.lux b/stdlib/source/lux/target/jvm/type/reflection.lux
index ffc26fb8b..1d6162838 100644
--- a/stdlib/source/lux/target/jvm/type/reflection.lux
+++ b/stdlib/source/lux/target/jvm/type/reflection.lux
@@ -1,12 +1,14 @@
 (.module:
   [lux (#- int char)
+   [abstract
+    [equivalence (#+ Equivalence)]]
    [data
-    [text
+    ["." text ("#@." equivalence)
      ["%" format (#+ format)]]]
    [type
     abstract]]
   ["." // #_
-   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter)]
+   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter Declaration)]
    ["#." descriptor]
    [//
     [encoding
@@ -21,6 +23,12 @@
     (-> (Reflection Any) Text)
     (|>> :representation))
 
+  (structure: #export equivalence
+    (All [category] (Equivalence (Reflection category)))
+    
+    (def: (= parameter subject)
+      (text@= (:representation parameter) (:representation subject))))
+
   (template [  ]
     [(def: #export 
        (Reflection )
@@ -41,11 +49,41 @@
     (-> External (Reflection Class))
     (|>> :abstraction))
 
-  (def: #export array
+  (def: #export (declaration name)
+    (-> External (Reflection Declaration))
+    (:transmutation (..class name)))
+
+  (def: #export as-class
+    (-> (Reflection Declaration) (Reflection Class))
+    (|>> :transmutation))
+
+  (def: #export (array element)
     (-> (Reflection Value) (Reflection Array))
-    (|>> :representation
-         (format //descriptor.array-prefix)
-         :abstraction))
+    (let [element' (:representation element)
+          elementR (`` (cond (text.starts-with? //descriptor.array-prefix element')
+                             element'
+                             
+                             (~~ (template [ ]
+                                   [(:: ..equivalence =  element)
+                                    (//descriptor.descriptor )]
+
+                                   [..boolean //descriptor.boolean]
+                                   [..byte //descriptor.byte]
+                                   [..short //descriptor.short]
+                                   [..int //descriptor.int]
+                                   [..long //descriptor.long]
+                                   [..float //descriptor.float]
+                                   [..double //descriptor.double]
+                                   [..char //descriptor.char]))
+
+                             (|> element'
+                                 //descriptor.class
+                                 //descriptor.descriptor
+                                 (text.replace-all //name.internal-separator
+                                                   //name.external-separator))))]
+      (|> elementR
+          (format //descriptor.array-prefix)
+          :abstraction)))
 
   (template [ ]
     [(def: #export 
diff --git a/stdlib/source/lux/target/jvm/type/signature.lux b/stdlib/source/lux/target/jvm/type/signature.lux
index 5a2256417..b88d3f610 100644
--- a/stdlib/source/lux/target/jvm/type/signature.lux
+++ b/stdlib/source/lux/target/jvm/type/signature.lux
@@ -11,7 +11,7 @@
    [type
     abstract]]
   ["." // #_
-   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter)]
+   [category (#+ Void Value Return Method Primitive Object Class Array Var Parameter Declaration)]
    ["#." descriptor]
    ["/#" // #_
     [encoding
@@ -91,6 +91,14 @@
                        ..parameters-end))
              //descriptor.class-suffix)))
 
+  (def: #export (declaration name variables)
+    (-> External (List (Signature Var)) (Signature Declaration))
+    (:transmutation (..class name variables)))
+
+  (def: #export as-class
+    (-> (Signature Declaration) (Signature Class))
+    (|>> :transmutation))
+
   (def: #export arguments-start "(")
   (def: #export arguments-end ")")
 
diff --git a/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux b/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux
index 1d5b1218d..769646ad0 100644
--- a/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux
+++ b/stdlib/source/lux/tool/compiler/phase/extension/analysis/jvm.lux
@@ -114,7 +114,7 @@
   )
 
 (template []
-  [(exception: #export ( {class Text})
+  [(exception: #export ( {class External})
      (exception.report
       ["Class/type" (%.text class)]))]
 
@@ -123,13 +123,13 @@
   [primitives-are-not-objects]
   )
 
-(exception: #export (cannot-set-a-final-field {field Text} {class Text})
+(exception: #export (cannot-set-a-final-field {field Text} {class External})
   (exception.report
    ["Field" (%.text field)]
    ["Class" (%.text class)]))
 
 (template []
-  [(exception: #export ( {class Text}
+  [(exception: #export ( {class External}
                                {method Text}
                                {inputsJT (List (Type Value))}
                                {hints (List Method-Signature)})
@@ -240,7 +240,7 @@
           )))
 
 (def: #export boxes
-  (Dictionary Text [Text (Type Primitive)])
+  (Dictionary External [External (Type Primitive)])
   (|> (list [(reflection.reflection reflection.boolean) [box.boolean jvm.boolean]]
             [(reflection.reflection reflection.byte)    [box.byte jvm.byte]]
             [(reflection.reflection reflection.short)   [box.short jvm.short]]
@@ -387,21 +387,18 @@
     (/////analysis.throw ..non-parameter objectT)
     
     (#.Primitive name parameters)
-    (`` (cond (~~ (template []
-                    [(text@= (reflection.reflection )
-                             name)
-                     (/////analysis.throw ..non-parameter objectT)]
-
-                    [reflection.boolean]
-                    [reflection.byte]
-                    [reflection.short]
-                    [reflection.int]
-                    [reflection.long]
-                    [reflection.float]
-                    [reflection.double]
-                    [reflection.char]))
-
-              (text.starts-with? descriptor.array-prefix name)
+    (`` (cond (or (~~ (template []
+                        [(text@= (..reflection ) name)]
+
+                        [jvm.boolean]
+                        [jvm.byte]
+                        [jvm.short]
+                        [jvm.int]
+                        [jvm.long]
+                        [jvm.float]
+                        [jvm.double]
+                        [jvm.char]))
+                  (text.starts-with? descriptor.array-prefix name))
               (/////analysis.throw ..non-parameter objectT)
 
               ## else
@@ -437,22 +434,36 @@
   (-> .Type (Operation (Type Value)))
   (case objectT
     (#.Primitive name #.Nil)
-    (`` (cond (~~ (template [ ]
-                    [(text@= (reflection.reflection )
-                             name)
+    (`` (cond (~~ (template []
+                    [(text@= (..reflection ) name)
                      (////@wrap )]
 
-                    [reflection.boolean jvm.boolean]
-                    [reflection.byte jvm.byte]
-                    [reflection.short jvm.short]
-                    [reflection.int jvm.int]
-                    [reflection.long jvm.long]
-                    [reflection.float jvm.float]
-                    [reflection.double jvm.double]
-                    [reflection.char jvm.char]))
+                    [jvm.boolean]
+                    [jvm.byte]
+                    [jvm.short]
+                    [jvm.int]
+                    [jvm.long]
+                    [jvm.float]
+                    [jvm.double]
+                    [jvm.char]))
+
+              (~~ (template []
+                    [(text@= (..reflection (jvm.array )) name)
+                     (////@wrap (jvm.array ))]
+
+                    [jvm.boolean]
+                    [jvm.byte]
+                    [jvm.short]
+                    [jvm.int]
+                    [jvm.long]
+                    [jvm.float]
+                    [jvm.double]
+                    [jvm.char]))
 
               (text.starts-with? descriptor.array-prefix name)
-              (////.lift (.run jvm-parser.value name))
+              (let [[_ unprefixed] (maybe.assume (text.split-with descriptor.array-prefix name))]
+                (:: ////.monad map jvm.array
+                    (check-jvm (#.Primitive unprefixed (list)))))
 
               ## else
               (////@wrap (jvm.class name (list)))))
@@ -800,7 +811,7 @@
     (////.fail error)))
 
 (def: (class-candidate-parents from-name fromT to-name to-class)
-  (-> Text .Type Text (java/lang/Class java/lang/Object) (Operation (List [[Text .Type] Bit])))
+  (-> External .Type External (java/lang/Class java/lang/Object) (Operation (List [[Text .Type] Bit])))
   (do ////.monad
     [from-class (////.lift (reflection!.load from-name))
      mapping (////.lift (reflection!.correspond from-class fromT))]
@@ -1012,8 +1023,8 @@
   #Special
   #Interface)
 
-(def: (check-method class method-name method-style inputsJT method)
-  (-> (java/lang/Class java/lang/Object) Text Method-Style (List (Type Value)) java/lang/reflect/Method (Operation Bit))
+(def: (check-method aliasing class method-name method-style inputsJT method)
+  (-> Aliasing (java/lang/Class java/lang/Object) Text Method-Style (List (Type Value)) java/lang/reflect/Method (Operation Bit))
   (do ////.monad
     [parameters (|> (java/lang/reflect/Method::getGenericParameterTypes method)
                     array.to-list
@@ -1027,20 +1038,29 @@
                              (java/lang/reflect/Modifier::isStatic modifiers)
 
                              _
-                             #1)
+                             true)
            special-matches? (case method-style
                               #Special
                               (not (or (java/lang/reflect/Modifier::isInterface (java/lang/Class::getModifiers class))
                                        (java/lang/reflect/Modifier::isAbstract modifiers)))
 
                               _
-                              #1)
+                              true)
            arity-matches? (n.= (list.size inputsJT) (list.size parameters))
            inputs-match? (list@fold (function (_ [expectedJC actualJC] prev)
                                       (and prev
-                                           (jvm@= expectedJC actualJC)))
-                                    #1
-                                    (list.zip2 inputsJT parameters))]]
+                                           (jvm@= expectedJC (: (Type Value)
+                                                                (case (jvm-parser.var? actualJC)
+                                                                  (#.Some name)
+                                                                  (|> aliasing
+                                                                      (dictionary.get name)
+                                                                      (maybe.default name)
+                                                                      jvm.var)
+
+                                                                  #.None
+                                                                  actualJC)))))
+                                    true
+                                    (list.zip2 parameters inputsJT))]]
     (wrap (and correct-class?
                correct-method?
                static-matches?
@@ -1048,8 +1068,8 @@
                arity-matches?
                inputs-match?))))
 
-(def: (check-constructor class inputsJT constructor)
-  (-> (java/lang/Class java/lang/Object) (List (Type Value)) (java/lang/reflect/Constructor java/lang/Object) (Operation Bit))
+(def: (check-constructor aliasing class inputsJT constructor)
+  (-> Aliasing (java/lang/Class java/lang/Object) (List (Type Value)) (java/lang/reflect/Constructor java/lang/Object) (Operation Bit))
   (do ////.monad
     [parameters (|> (java/lang/reflect/Constructor::getGenericParameterTypes constructor)
                     array.to-list
@@ -1059,9 +1079,18 @@
                (n.= (list.size inputsJT) (list.size parameters))
                (list@fold (function (_ [expectedJC actualJC] prev)
                             (and prev
-                                 (jvm@= expectedJC actualJC)))
-                          #1
-                          (list.zip2 inputsJT parameters))))))
+                                 (jvm@= expectedJC (: (Type Value)
+                                                      (case (jvm-parser.var? actualJC)
+                                                        (#.Some name)
+                                                        (|> aliasing
+                                                            (dictionary.get name)
+                                                            (maybe.default name)
+                                                            jvm.var)
+
+                                                        #.None
+                                                        actualJC)))))
+                          true
+                          (list.zip2 parameters inputsJT))))))
 
 (def: idx-to-parameter
   (-> Nat .Type)
@@ -1168,10 +1197,29 @@
   [hint! #Hint]
   )
 
-(def: (method-candidate class-name method-name method-style inputsJT)
-  (-> Text Text Method-Style (List (Type Value)) (Operation Method-Signature))
+(template [  ]
+  [(def: 
+     (->  (List (Type Var)))
+     (|>> 
+          array.to-list
+          (list@map (|>> java/lang/reflect/TypeVariable::getName jvm.var))))]
+
+  [class-type-variables (java/lang/Class java/lang/Object) java/lang/Class::getTypeParameters]
+  [constructor-type-variables (java/lang/reflect/Constructor java/lang/Object) java/lang/reflect/Constructor::getTypeParameters]
+  [method-type-variables java/lang/reflect/Method java/lang/reflect/Method::getTypeParameters]
+  )
+
+(def: (aliasing expected actual)
+  (-> (List (Type Var)) (List (Type Var)) Aliasing)
+  (|> (list.zip2 (list@map jvm-parser.name actual)
+                 (list@map jvm-parser.name expected))
+      (dictionary.from-list text.hash)))
+
+(def: (method-candidate actual-class-tvars class-name actual-method-tvars method-name method-style inputsJT)
+  (-> (List (Type Var)) External (List (Type Var)) Text Method-Style (List (Type Value)) (Operation Method-Signature))
   (do ////.monad
     [class (////.lift (reflection!.load class-name))
+     #let [expected-class-tvars (class-type-variables class)]
      candidates (|> class
                     java/lang/Class::getDeclaredMethods
                     array.to-list
@@ -1179,7 +1227,10 @@
                     (monad.map @ (: (-> java/lang/reflect/Method (Operation Evaluation))
                                     (function (_ method)
                                       (do @
-                                        [passes? (check-method class method-name method-style inputsJT method)]
+                                        [#let [expected-method-tvars (method-type-variables method)
+                                               aliasing (dictionary.merge (..aliasing expected-class-tvars actual-class-tvars)
+                                                                          (..aliasing expected-method-tvars actual-method-tvars))]
+                                         passes? (check-method aliasing class method-name method-style inputsJT method)]
                                         (:: @ map (if passes?
                                                     (|>> #Pass)
                                                     (|>> #Hint))
@@ -1196,16 +1247,20 @@
 
 (def: constructor-method "")
 
-(def: (constructor-candidate class-name inputsJT)
-  (-> Text (List (Type Value)) (Operation Method-Signature))
+(def: (constructor-candidate actual-class-tvars class-name actual-method-tvars inputsJT)
+  (-> (List (Type Var)) External (List (Type Var)) (List (Type Value)) (Operation Method-Signature))
   (do ////.monad
     [class (////.lift (reflection!.load class-name))
+     #let [expected-class-tvars (class-type-variables class)]
      candidates (|> class
                     java/lang/Class::getConstructors
                     array.to-list
                     (monad.map @ (function (_ constructor)
                                    (do @
-                                     [passes? (check-constructor class inputsJT constructor)]
+                                     [#let [expected-method-tvars (constructor-type-variables constructor)
+                                            aliasing (dictionary.merge (..aliasing expected-class-tvars actual-class-tvars)
+                                                                       (..aliasing expected-method-tvars actual-method-tvars))]
+                                      passes? (check-constructor aliasing class inputsJT constructor)]
                                      (:: @ map
                                          (if passes? (|>> #Pass) (|>> #Hint))
                                          (constructor-signature constructor))))))]
@@ -1241,14 +1296,16 @@
       (list@map (function (_ [type value])
                   (/////analysis.tuple (list type value))))))
 
+(def: type-vars (.tuple (<>.some ..var)))
+
 (def: invoke::static
   Handler
   (..custom
-   [($_ <>.and ..member (<>.some ..input))
-    (function (_ extension-name analyse [[class method] argsTC])
+   [($_ <>.and ..type-vars ..member ..type-vars (<>.some ..input))
+    (function (_ extension-name analyse [class-tvars [class method] method-tvars argsTC])
       (do ////.monad
         [#let [argsT (list@map product.left argsTC)]
-         [methodT exceptionsT] (method-candidate class method #Static argsT)
+         [methodT exceptionsT] (method-candidate class-tvars class method-tvars method #Static argsT)
          [outputT argsA] (inferenceA.general analyse methodT (list@map product.right argsTC))
          outputJC (check-return outputT)]
         (wrap (#/////analysis.Extension extension-name (list& (/////analysis.text (..signature (jvm.class class (list))))
@@ -1259,11 +1316,11 @@
 (def: invoke::virtual
   Handler
   (..custom
-   [($_ <>.and ..member .any (<>.some ..input))
-    (function (_ extension-name analyse [[class method] objectC argsTC])
+   [($_ <>.and ..type-vars ..member ..type-vars .any (<>.some ..input))
+    (function (_ extension-name analyse [class-tvars [class method] method-tvars objectC argsTC])
       (do ////.monad
         [#let [argsT (list@map product.left argsTC)]
-         [methodT exceptionsT] (method-candidate class method #Virtual argsT)
+         [methodT exceptionsT] (method-candidate class-tvars class method-tvars method #Virtual argsT)
          [outputT allA] (inferenceA.general analyse methodT (list& objectC (list@map product.right argsTC)))
          #let [[objectA argsA] (case allA
                                  (#.Cons objectA argsA)
@@ -1281,11 +1338,11 @@
 (def: invoke::special
   Handler
   (..custom
-   [($_ <>.and ..member .any (<>.some ..input))
-    (function (_ extension-name analyse [[class method] objectC argsTC])
+   [($_ <>.and ..type-vars ..member ..type-vars .any (<>.some ..input))
+    (function (_ extension-name analyse [class-tvars [class method] method-tvars objectC argsTC])
       (do ////.monad
         [#let [argsT (list@map product.left argsTC)]
-         [methodT exceptionsT] (method-candidate class method #Special argsT)
+         [methodT exceptionsT] (method-candidate class-tvars class method-tvars method #Special argsT)
          [outputT argsA] (inferenceA.general analyse methodT (list& objectC (list@map product.right argsTC)))
          outputJC (check-return outputT)]
         (wrap (#/////analysis.Extension extension-name (list& (/////analysis.text (..signature (jvm.class class (list))))
@@ -1296,14 +1353,14 @@
 (def: invoke::interface
   Handler
   (..custom
-   [($_ <>.and ..member .any (<>.some ..input))
-    (function (_ extension-name analyse [[class-name method] objectC argsTC])
+   [($_ <>.and ..type-vars ..member ..type-vars .any (<>.some ..input))
+    (function (_ extension-name analyse [class-tvars [class-name method] method-tvars objectC argsTC])
       (do ////.monad
         [#let [argsT (list@map product.left argsTC)]
          class (////.lift (reflection!.load class-name))
          _ (////.assert non-interface class-name
                         (java/lang/reflect/Modifier::isInterface (java/lang/Class::getModifiers class)))
-         [methodT exceptionsT] (method-candidate class-name method #Interface argsT)
+         [methodT exceptionsT] (method-candidate class-tvars class-name method-tvars method #Interface argsT)
          [outputT allA] (inferenceA.general analyse methodT (list& objectC (list@map product.right argsTC)))
          #let [[objectA argsA] (case allA
                                  (#.Cons objectA argsA)
@@ -1321,11 +1378,11 @@
 
 (def: invoke::constructor
   (..custom
-   [($_ <>.and .text (<>.some ..input))
-    (function (_ extension-name analyse [class argsTC])
+   [($_ <>.and ..type-vars .text ..type-vars (<>.some ..input))
+    (function (_ extension-name analyse [class-tvars class method-tvars argsTC])
       (do ////.monad
         [#let [argsT (list@map product.left argsTC)]
-         [methodT exceptionsT] (constructor-candidate class argsT)
+         [methodT exceptionsT] (constructor-candidate class-tvars class method-tvars argsT)
          [outputT argsA] (inferenceA.general analyse methodT (list@map product.right argsTC))]
         (wrap (#/////analysis.Extension extension-name (list& (/////analysis.text (..signature (jvm.class class (list))))
                                                               (decorate-inputs argsT argsA))))))]))
-- 
cgit v1.2.3