Nested sealed classes and "when"


#1

Hi, i’m trying out a construct like this:

sealed class UIEvent {
    class UsernameEvent : UIEvent()
    sealed class PasswordEvent : UIEvent() {
        class OnChangeText : PasswordEvent()
        class OnBlur : PasswordEvent()
    }
}

I tried handling it like this, but I get an error that PasswordEvent isn’t handled.

fun handle(ev: UIEvent): String = when (ev) {
    is UIEvent.UsernameEvent -> ""
    is UIEvent.PasswordEvent.OnChangeText -> ""
    is UIEvent.PasswordEvent.OnBlur -> ""
}

This would also be nice, but the inner when isn’t casted, and it complains about Username Event not being handled:

fun handle(ev: UIEvent): String = when (ev) {
    is UIEvent.UsernameEvent -> "a"
    is UIEvent.PasswordEvent -> when(ev) {
        is UIEvent.PasswordEvent.OnBlur -> "b"
        is UIEvent.PasswordEvent.OnChangeText -> "c"
    }
}

A follow-up question: Why do I have to manually import the sealed classes, in order to remove the prefix in the branches? This is a bit tedious especially because the IDEA plugin can’t resolve the reference automatically.

Thank you.


#2

There is an existing issue about this: https://youtrack.jetbrains.com/issue/KT-10648. You can expect it to be resolved in near future (well, probably in 1.1). As a temporary workaround, you can add an explicit cast to the inner when: when (ev as UIEvent.PasswordEvent) { … }.


#3

About follow-up: I rechecked it and was able to make import automatically. To be precise, I wrote “is PasswordEvent”, first Alt+Enter gave me “is UIEvent.PasswordEvent” and the second Alt+Enter imported PasswordEvent and rolled back to “is PasswordEvent”. It this the thing you had in mind? If no, please write more details.


#4

You are right, when I tried now, it worked like you said.

Maybe I had compile errors somewhere else in the same file. I get back with more details when it happens again.