Add Kotlin generic type projections
ober
75fe436882fc90a2d8375b8f2000e6a829f77b7c
--- a/lib/jerboa/typed/checker.ss +++ b/lib/jerboa/typed/checker.ss @@ -56,6 +56,8 @@ (Map . 2) (Set . 1) (MutableSet . 1) + (Out . 1) + (In . 1) (Nullable . 1) (Option . 1) (Result . 2) --- a/lib/jerboa/typed/kotlin/ast.ss +++ b/lib/jerboa/typed/kotlin/ast.ss @@ -16,6 +16,8 @@ kt-type? make-kt-type kt-type-name kt-type-nullable? kt-type-args + kt-type-projection? make-kt-type-projection + kt-type-projection-variance kt-type-projection-type kt-param? make-kt-param kt-param-name kt-param-type kt-param-default @@ -136,6 +138,7 @@ ;; Types. `name` is a symbol, string, or list of package/name parts. (defstruct kt-type (name nullable? args)) + (defstruct kt-type-projection (variance type)) ;; Function/constructor parameters. When `property` is 'val or 'var, the ;; printer emits the parameter as a Kotlin primary-constructor property. --- a/lib/jerboa/typed/kotlin/lower.ss +++ b/lib/jerboa/typed/kotlin/lower.ss @@ -108,6 +108,10 @@ (make-kt-type 'List #f (list (typed-type->kotlin-type (cadr type))))] [(and (pair? type) (eq? (car type) 'Array)) (make-kt-type 'Array #f (list (typed-type->kotlin-type (cadr type))))] + [(and (pair? type) (eq? (car type) 'Out)) + (make-kt-type-projection 'out (typed-type->kotlin-type (cadr type)))] + [(and (pair? type) (eq? (car type) 'In)) + (make-kt-type-projection 'in (typed-type->kotlin-type (cadr type)))] [(and (pair? type) (eq? (car type) 'Vector)) (make-kt-type 'List #f (list (typed-type->kotlin-type (cadr type))))] [(and (pair? type) (eq? (car type) 'MutableList)) --- a/lib/jerboa/typed/kotlin/print.ss +++ b/lib/jerboa/typed/kotlin/print.ss @@ -203,6 +203,11 @@ (join-strings (map kotlin-type->string args) ", ") ">")) (if (kt-type-nullable? type) "?" "")))] + [(kt-type-projection? type) + (string-append + (kotlin-modifier->string (kt-type-projection-variance type)) + " " + (kotlin-type->string (kt-type-projection-type type)))] [(symbol? type) (kotlin-symbol-name type)] [(string? type) (sanitize-kotlin-ident type)] [else (error 'kotlin-type->string "not a Kotlin type" type)])) --- a/tests/test-typed-kotlin.ss +++ b/tests/test-typed-kotlin.ss @@ -70,6 +70,17 @@ (make-kt-member-call (make-kt-name '(ch)) 'isLetterOrDigit '()))) "{ ch -> ch.isLetterOrDigit() }") +(test "Kotlin type projection printer" + (kotlin-type->string + (make-kt-type + 'Array + #f + (list + (make-kt-type-projection + 'out + (make-kt-type 'String #f '()))))) + "Array<out String>") + (test "checked cast expression printer" (kotlin-expr->string (make-kt-cast @@ -1650,6 +1661,15 @@ (define param-options-kotlin (typed-library-form->kotlin-string param-options-form)) +(define type-projection-form + '(typed-library (sample typed projection) + (export use-permissions) + (def (use-permissions (permissions : (Array (Out String)))) : Unit + (begin)))) + +(define type-projection-kotlin + (typed-library-form->kotlin-string type-projection-form)) + (test-contains "typed class declaration lowers constructor and superclass" class-declaration-kotlin "class ReviewView(context: Context) : View(context) {") @@ -1689,6 +1709,9 @@ (test-contains "typed function parameter lowers vararg modifier" param-options-kotlin "fun row(vararg buttons: Button): Unit") +(test-contains "typed Out type projection lowers to Kotlin out projection" + type-projection-kotlin + "fun use_permissions(permissions: Array<out String>): Unit") (test-contains "typed def kotlin-name lowers emitted method name" kotlin-name-kotlin "override fun read(): Int")