Add typed Kotlin cast externs
ober
344119da5afd49cc97ed78676474b98d0da8fc97
--- a/lib/jerboa/typed/checker.ss +++ b/lib/jerboa/typed/checker.ss @@ -412,6 +412,8 @@ [(external) 'kotlin-call] [(call) 'kotlin-call] [(value) 'kotlin-value] + [(cast) 'kotlin-cast] + [(safe-cast) 'kotlin-safe-cast] [(member-call) 'kotlin-member-call] [(member-get) 'kotlin-member-get] [(member-set) 'kotlin-member-set] --- a/lib/jerboa/typed/core.ss +++ b/lib/jerboa/typed/core.ss @@ -218,6 +218,8 @@ debug-string kotlin-call kotlin-value + kotlin-cast + kotlin-safe-cast kotlin-member-call kotlin-member-get kotlin-member-set --- a/lib/jerboa/typed/kotlin/ast.ss +++ b/lib/jerboa/typed/kotlin/ast.ss @@ -82,6 +82,9 @@ kt-member-get? make-kt-member-get kt-member-get-target kt-member-get-name + kt-cast? make-kt-cast + kt-cast-expr kt-cast-type kt-cast-safe? + kt-index-get? make-kt-index-get kt-index-get-target kt-index-get-index @@ -165,6 +168,7 @@ (defstruct kt-call (callee args)) (defstruct kt-member-call (target name args)) (defstruct kt-member-get (target name)) + (defstruct kt-cast (expr type safe?)) (defstruct kt-index-get (target index)) (defstruct kt-lambda (params body)) (defstruct kt-object-expr (super-types body)) --- a/lib/jerboa/typed/kotlin/lower.ss +++ b/lib/jerboa/typed/kotlin/lower.ss @@ -664,6 +664,20 @@ (make-kt-call (make-kt-name (info-ref info 'path (list operator))) args)] [(kotlin-value) (make-kt-name (info-ref info 'path (list operator)))] + [(kotlin-cast) + (make-kt-cast + (car args) + (typed-type->kotlin-type (info-ref info 'type (typed-ir-node-type ir))) + #f)] + [(kotlin-safe-cast) + (make-kt-cast + (car args) + (typed-type->kotlin-type + (let ([target-type (info-ref info 'type (typed-ir-node-type ir))]) + (if (and (pair? target-type) (eq? (car target-type) 'Nullable)) + (cadr target-type) + target-type))) + #t)] [(kotlin-member-call) (make-kt-member-call (car args) --- a/lib/jerboa/typed/kotlin/print.ss +++ b/lib/jerboa/typed/kotlin/print.ss @@ -262,6 +262,7 @@ (kt-try-finally? expr) (kt-block? expr) (kt-when? expr) + (kt-cast? expr) (kt-object-expr? expr) (kt-lambda? expr))) @@ -309,6 +310,12 @@ (kotlin-member-target->string (kt-member-get-target expr)) "." (kotlin-member-name (kt-member-get-name expr)))] + [(kt-cast? expr) + (parenthesize + (string-append + (kotlin-expr->string (kt-cast-expr expr)) + (if (kt-cast-safe? expr) " as? " " as ") + (kotlin-type->string (kt-cast-type expr))))] [(kt-index-get? expr) (string-append (kotlin-member-target->string (kt-index-get-target expr)) --- a/lib/jerboa/typed/parser.ss +++ b/lib/jerboa/typed/parser.ss @@ -661,6 +661,14 @@ (list (cons 'kind 'value) (cons 'path (cdr form)))] [(and (= (length form) 2) + (eq? (car form) 'kotlin-cast)) + (list (cons 'kind 'cast) + (cons 'type (parse-typed-type (cadr form))))] + [(and (= (length form) 2) + (eq? (car form) 'kotlin-safe-cast)) + (list (cons 'kind 'safe-cast) + (cons 'type (parse-typed-type (cadr form))))] + [(and (= (length form) 2) (eq? (car form) 'kotlin-member-call) (symbol? (cadr form))) (list (cons 'kind 'member-call) @@ -680,7 +688,7 @@ (list (cons 'kind 'external))] [else (error 'parse-typed-extern - "expected (kotlin-call PackageOrObject function), (kotlin-value PackageOrObject property), (kotlin-member-call method), (kotlin-member-get property), (kotlin-member-set property), or (kotlin-external)" + "expected (kotlin-call PackageOrObject function), (kotlin-value PackageOrObject property), (kotlin-cast Type), (kotlin-safe-cast Type), (kotlin-member-call method), (kotlin-member-get property), (kotlin-member-set property), or (kotlin-external)" form)]))) (def (parse-extern form) --- a/tests/test-typed-checker.ss +++ b/tests/test-typed-checker.ss @@ -652,6 +652,22 @@ (reviewViewSelectedGroupId-set view id)))) '()) +(test "extern kotlin cast forms can be used from typed code" + (error-kinds + '(typed-library (body extern-cast-ok) + (export checked safe) + (type Any) + (type HttpsURLConnection) + (extern (asHttpsURLConnection (value : Any)) : HttpsURLConnection + (kotlin-cast HttpsURLConnection)) + (extern (asHttpsURLConnectionOrNull (value : Any)) : (Nullable HttpsURLConnection) + (kotlin-safe-cast HttpsURLConnection)) + (def (checked (value : Any)) : HttpsURLConnection + (asHttpsURLConnection value)) + (def (safe (value : Any)) : (Nullable HttpsURLConnection) + (asHttpsURLConnectionOrNull value)))) + '()) + (test "effect annotation accepted" (error-kinds '(typed-library (effects accepted) --- a/tests/test-typed-kotlin.ss +++ b/tests/test-typed-kotlin.ss @@ -70,6 +70,22 @@ (make-kt-member-call (make-kt-name '(ch)) 'isLetterOrDigit '()))) "{ ch -> ch.isLetterOrDigit() }") +(test "checked cast expression printer" + (kotlin-expr->string + (make-kt-cast + (make-kt-name '(connection)) + (make-kt-type 'HttpsURLConnection #f '()) + #f)) + "(connection as HttpsURLConnection)") + +(test "safe cast expression printer" + (kotlin-expr->string + (make-kt-cast + (make-kt-name '(connection)) + (make-kt-type 'HttpsURLConnection #f '()) + #t)) + "(connection as? HttpsURLConnection)") + (test "zero-argument lambda expression printer" (kotlin-expr->string (make-kt-lambda @@ -344,6 +360,7 @@ (define extern-form '(typed-library (sample typed extern) (export find defaultOptions) + (type Any) (type Context) (type BoxType) (type TextRecognizerOptions) @@ -351,10 +368,18 @@ (kotlin-call BoxTypes resolve)) (extern (textRecognizerDefaultOptions) : TextRecognizerOptions (kotlin-value TextRecognizerOptions DEFAULT_OPTIONS)) + (extern (asRecognizer (value : Any)) : TextRecognizerOptions + (kotlin-cast TextRecognizerOptions)) + (extern (maybeBoxType (value : Any)) : (Nullable BoxType) + (kotlin-safe-cast BoxType)) (def (find (context : Context) (raw : String)) : (Nullable BoxType) (boxTypesResolve context raw)) (def (defaultOptions) : TextRecognizerOptions - (textRecognizerDefaultOptions)))) + (textRecognizerDefaultOptions)) + (def (castRecognizer (value : Any)) : TextRecognizerOptions + (asRecognizer value)) + (def (safeCastBoxType (value : Any)) : (Nullable BoxType) + (maybeBoxType value)))) (define extern-kotlin (typed-library-form->kotlin-string extern-form)) @@ -366,6 +391,14 @@ extern-kotlin "return TextRecognizerOptions.DEFAULT_OPTIONS") +(test-contains "extern Kotlin cast lowers to checked cast" + extern-kotlin + "return (value as TextRecognizerOptions)") + +(test-contains "extern Kotlin safe cast lowers to nullable checked cast" + extern-kotlin + "return (value as? BoxType)") + (define member-extern-form '(typed-library (sample typed memberextern) (export width copyPixels setSelectedGroup)