Consider to implicitly apply Serializable annotation to the entire sealed hierarchy
What is your use-case and why do you need this feature?
Parcelize allows the following code.
@Parcelize
sealed interface State : Parcelable {
data object Loading : State
data object Error : State
data class Data(val data: String) : State
}
We are able to specify the annotation only once on the base State interface. With kotlinx-serialization we have to repeat the annotation for every implementing class, which is pretty verbose.
@Serializable
sealed interface State {
@Serializable
data object Loading : State
@Serializable
data object Error : State
@Serializable
data class Data(val data: String) : State
}
Describe the solution you'd like
It would be nice to be able to write as follows.
@Serializable
sealed interface State {
data object Loading : State
data object Error : State
data class Data(val data: String) : State
}
Alternative API if changing the existing behaviour is undesirable.
@Serializable(inherited = true)
sealed interface State {
data object Loading : State
data object Error : State
data class Data(val data: String) : State
}
Given that inheritors of the sealed interface can be defined anywhere in the project, and it is not mandatory for them to be in the same file, this would be hard from a technical standpoint: it would require the plugin to analyze every single class in the project and its superclasses, instead of focusing on @Serializable classes. It also brings questions for design: if my intention to have only some of the inheritors serializable, how can I opt-out?
To sum up, we cannot change the behavior of the existing @Serializable annotation, as it would not be backward-compatible. It is possible to implement additional annotation though, that would cover the exact use case you've presented here. E.g. @SerializableSubclasses for nested classes or classes in the same file.
@SerializableSubclasses sounds good as well. What about adding an optional argument to @Serializable? E.g. inherited: Boolean with default value false to keep the current behaviour as default, and make the new feature opt-in.
@Serializable also can be applied to the properties to specify custom serializer, so inherited parameter there would look illogical.
In some way the serializable annotation adds an expectation to the type (in that a valid expectation could be that all its subclasses/implementations are also serializable).
On the other hand there may be implementations that can not be serializable (and the parent must be to support serializability of the sibling) – This is more of an "abstract serializability" (often with abstract base types).
Given this dichotomy it seems that either a different annotation (or parameter) would work (as well as maybe have the plugin generate warnings on missing child serializers).
The biggest challenge I see is the change of annotations being an API change