You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If I want to define a class hierarchy of small serializable classes, the @Serializable annotation can become painfully redundant. This can make the code at worst twice as long, and reduces the readability significantly.
Before writing this, I considered some previous requests. These requests were similar, but none quite captured the idea this way, so I thought it would be worth it to create a new issue.
The important details for my proposal are:
If our computer screen is capable of fitting, say, 10 class definitions on it, it would be good to just see a single annotation saying "all of these classes are serializable"
This proposal does not change the current behavior of @Serializable, it is backwards compatible.
This proposal is for a new annotation (or possible new target site of @Serializable). It simple reads as "all of these classes you see here will have generated serializers".
This annotation, in its simplest form, does not need to have any arguments.
Here is some code the exemplifies the main issue. This code is made twice as long because of all of the Serializable annotations.
@Serializable
classZoo(valanimals:Set<Animal>)
@Serializable
sealedinterfaceAnimal
@Serializable
data classPenguin(valname:String, valage:Int, valisHappyFeet:Boolean): Animal
@Serializable
data classLion(valname:String, valmaneLength:Int): Animal
@Serializable
data classElephant(valname:String, valtrunkLength:Int, valweight:Int): Animal
@Serializable
data classMonkey(valname:String, valfavoriteFood:String): Animal
@Serializable
data classGiraffe(valname:String, valneckLength:Int): Animal
@Serializable
data classTiger(valname:String, valstripeCount:Int): Animal
@Serializable
data classZebra(valname:String, valstripePattern:String): Animal
@Serializable
data classParrot(valname:String, valcanTalk:Boolean): Animal
@Serializable
data classSnake(valname:String, vallength:Int): Animal
@Serializable
data classBear(valname:String, valtype:String): Animal
This propsal is for an annotation such as:
@AllSerializable
object ZooClasses {
classZoo(valanimals:Set<Animal>)
sealedinterfaceAnimaldata classPenguin(valname:String, valage:Int, valisHappyFeet:Boolean): Animal
data classLion(valname:String, valmaneLength:Int): Animal
data classElephant(valname:String, valtrunkLength:Int, valweight:Int): Animal
data classMonkey(valname:String, valfavoriteFood:String): Animal
data classGiraffe(valname:String, valneckLength:Int): Animal
data classTiger(valname:String, valstripeCount:Int): Animal
data classZebra(valname:String, valstripePattern:String): Animal
data classParrot(valname:String, valcanTalk:Boolean): Animal
data classSnake(valname:String, vallength:Int): Animal
data classBear(valname:String, valtype:String): Animal
}
My idea is that ZooClasses itself is not made serializable from @AllSerializable, but that detail can be changed.
One workaround to reduce the number of lines is to put @Serializable on the same line as the definition like:
@Serializable data classBear(valname:String, valtype:String): Animal
However, has a couple issues:
It will usually break formatter rules, so these formatter rules would have to be suppressed on the file
It adds significant width to each line, makes them less readable, and reduces how many properties can fit on one line
For my example, I used single-line class definitions to highlight the issue. However, even for more typical class definitons that are multiple lines, this issue still matters.
I think this might be something that is possible to implement without many issues. When the compiler plugin sees @AllSerializable, it behaves exactly as if each nested class had @Serializable.
If a class inside ZooClasses has @Serializable with no arguments, the behavior is the same. There could be a warning inidicating the redundancy.
If a class inside ZooClasses has @Serializable with a custom serializer, the custom serializer is generated like normal, and the plugin does not do anything special (it doesn't generate two serializers)
This would also work with objects and enums, following the same logic.
There are no special rules or requirements regarding sealed classes/interfaces. Using AllSerializable would behave exactly like putting Serializable on each individual class or object inside the group.
Whether a class is inner or not doesn't matter. The only thing that matters is class nesting.
@file:Serializable or @file:AllSerializable could possibly be implemented as part of this. However, @file annotations are easy to miss since they are above the import statements. I think including @file annotations could make this request more controversial, so I propose not to include them (at least for now).
Here is how this request is different from similar previous requests:
This request was for plugin-wide automatic serializers. It was closed without fixing based on conerns about readability, security, and performance and I think none of the issues mentioned there apply here
This request is for applying @Serializable based on sealed class hierarchy. Although the motivations are overlapping, the implementation in my proposal is different. My proposal is about applying an annotation based on being close together in the file and nothing to do with class hierarchies. I think that all of the issues mentioned by @sandwwraith in his comment for that issue are addressed and solved in my proposal:
it would require the plugin to analyze every single class in the project and its superclasses
This will not be an issue here, because this feature is based on an annotation. The compiler plugin will have to handle each annotation by checking nested classes, but I think that seems very small compared to scanning the whole module.
if my intention to have only some of the inheritors serializable, how can I opt-out?
Since this is just based on being a nested class in the annotated group, opting-out is as simple as moving the class you don't want to serialize outside of the class or object annotated with @AllSerializable.
@SerializableSubclasses for nested classes or classes in the same file
in that comment. I wasn't sure exactly what that meant, but to be clear this proposal is for an annotation that doesn't care whatsover about subclasses. I think that would help make this annotation be more simple and readable.
The text was updated successfully, but these errors were encountered:
If I want to define a class hierarchy of small serializable classes, the
@Serializable
annotation can become painfully redundant. This can make the code at worst twice as long, and reduces the readability significantly.Before writing this, I considered some previous requests. These requests were similar, but none quite captured the idea this way, so I thought it would be worth it to create a new issue.
The important details for my proposal are:
@Serializable
, it is backwards compatible.@Serializable
). It simple reads as "all of these classes you see here will have generated serializers".Here is some code the exemplifies the main issue. This code is made twice as long because of all of the
Serializable
annotations.This propsal is for an annotation such as:
My idea is that
ZooClasses
itself is not made serializable from@AllSerializable
, but that detail can be changed.One workaround to reduce the number of lines is to put
@Serializable
on the same line as the definition like:However, has a couple issues:
For my example, I used single-line class definitions to highlight the issue. However, even for more typical class definitons that are multiple lines, this issue still matters.
I think this might be something that is possible to implement without many issues. When the compiler plugin sees
@AllSerializable
, it behaves exactly as if each nested class had@Serializable
.If a class inside
ZooClasses
has@Serializable
with no arguments, the behavior is the same. There could be a warning inidicating the redundancy.If a class inside
ZooClasses
has@Serializable
with a custom serializer, the custom serializer is generated like normal, and the plugin does not do anything special (it doesn't generate two serializers)This would also work with
object
s andenum
s, following the same logic.There are no special rules or requirements regarding
sealed
classes/interfaces. UsingAllSerializable
would behave exactly like puttingSerializable
on each individual class or object inside the group.Whether a class is
inner
or not doesn't matter. The only thing that matters is class nesting.@file:Serializable
or@file:AllSerializable
could possibly be implemented as part of this. However,@file
annotations are easy to miss since they are above the import statements. I think including@file
annotations could make this request more controversial, so I propose not to include them (at least for now).Here is how this request is different from similar previous requests:
This request was for plugin-wide automatic serializers. It was closed without fixing based on conerns about readability, security, and performance and I think none of the issues mentioned there apply here
This request was closed for the same reasons as 1808, which I think are resolved here
This request is for applying
@Serializable
based on sealed class hierarchy. Although the motivations are overlapping, the implementation in my proposal is different. My proposal is about applying an annotation based on being close together in the file and nothing to do with class hierarchies. I think that all of the issues mentioned by @sandwwraith in his comment for that issue are addressed and solved in my proposal:This will not be an issue here, because this feature is based on an annotation. The compiler plugin will have to handle each annotation by checking nested classes, but I think that seems very small compared to scanning the whole module.
Since this is just based on being a nested class in the annotated group, opting-out is as simple as moving the class you don't want to serialize outside of the class or object annotated with
@AllSerializable
.This proposal should be backwards compatible
Note also that @sandwwraith mentioned the idea of
in that comment. I wasn't sure exactly what that meant, but to be clear this proposal is for an annotation that doesn't care whatsover about subclasses. I think that would help make this annotation be more simple and readable.
The text was updated successfully, but these errors were encountered: