Enum class derived from numeric type (C-type enums)

Many libraries make extensive use of numeric enums.
Android programming has a special annotation @IntDef to provide value checking.
However, defining numeric enums is cumberson:

// TODAY:

@NavigationMode var mode: Int = NAVIGATION_MODE_STANDARD

companion object {
    @Retention(AnnotationRetention.SOURCE)
    @IntDef(NAVIGATION_MODE_STANDARD.toLong(), NAVIGATION_MODE_LIST.toLong(), NAVIGATION_MODE_TABS.toLong())
    annotation class NavigationMode
    const val NAVIGATION_MODE_STANDARD = 0
    const val NAVIGATION_MODE_LIST = 1
    const val NAVIGATION_MODE_TABS = 2
}

It would by nice to be able to define numeric enums as easily as Java enums by declaring an integer numeric supertype.

// PROPOSAL:

var mode: NavigationMode = NAVIGATION_MODE_STANDARD

enum class NavigationMode: Int {   // Int as superclass
    NAVIGATION_MODE_STANDARD,
    NAVIGATION_MODE_LIST,
    NAVIGATION_MODE_TABS
}

At bytecode level, this should produce the same code as @IntDef above. In this case, field mode is of type Int. All enum elements are inlined numeric constants. Assignment of numeric values should be possible, creating warnings if the value cannot be guaranteed to match an enum value. Exhaustive when statements can be supported.

Explicit values can be supplied with constructor parameters:

enum class NavigationMode: Int {
    NAVIGATION_MODE_STANDARD(-1),
    NAVIGATION_MODE_LIST(1),
    NAVIGATION_MODE_TABS(4)
}

As an optional feature, the compiler could create a StringArray or Map with the names of the elements (for logging), such that NavigationMode.names[1] returns "NAVIGATION_MODE_LIST".

At least Int and Long should by available as numeric supertypes. Short and Byte would also be useful, but may be harder since they lack respective literals in the JVM.

5 Likes