The introduction of inline classes is a really nice feature, but they could be even more useful if they can be used as values in annotation classes as well. This feature would be limited to inline classes that are backed by known supported types.
Given the following example:
// Allow inline classes in annotations when backed by primitive types, etc.
annotation class Handler(val priority: Priority = Priority.Normal)
inline class Priority(val value: Int) {
companion object {
// Allow constant values for inline classes backed by primitive types, etc.
const val First = Priority(1000)
const val Normal = Priority(500)
const val Last = Priority(0)
}
}
inline class Priority(val value: Int) {
init {
require ( value > 0)
}
}
const val Last = Priority(0) invokes the constructor? What happens?
A fail in the requirement raises in the annotated class loading?
How handle future changes in the init block, like require ( value in 1..100)?
Since it’s a constant value that will be inlined it will never the call the init block directly. If the init block will ever be supported for inline classes.
There’re two options as far I can see:
Ignore the init block when used in annotations.
Call the init block in the static initializer of the class where the constant is defined.
There is a fourth option. Enforce that the init block can be executed at compile time. That way restrictions like i > 0 can be enforced there.
Arguabley this is a bit more complex and would probably require the existence of constexpr in kotlin first (I think there is an existing issue for that). This could also be added at a later point if we go with @fatjoe79’s option number 3.