https://kotlinlang.org logo
#codereview
Title
# codereview
l

louiscad

08/11/2018, 8:46 AM
Hi, anyone knows how I can make the following snippet more safe?
Copy code
/** Matches [android.support.v7.app.AppCompatViewInflater.createView] content. */
val appCompatViewFactory = { clazz: Class<out View>, context: Context, _: Style<out View>? ->
    when (clazz) {
        TextView::class.java -> AppCompatTextView(context)
        Button::class.java -> AppCompatButton(context)
        ImageView::class.java -> AppCompatImageView(context)
        EditText::class.java -> AppCompatEditText(context)
        ...
        else -> null
    }
}
The issue is that there's no type check, I could return anything for anytype and the compiler won't fail. I want to make sure each when branch returns an object of the type of the case on which it matched.
a

Andreas Sinz

08/11/2018, 9:02 AM
there is no way to do that in kotlin
l

louiscad

08/11/2018, 9:03 AM
I think I'll submit an issue. This could definitely be supported in some way
a

Andreas Sinz

08/11/2018, 9:04 AM
how would that work?
l

louiscad

08/11/2018, 9:07 AM
Allowing reification of
Class<*>
and smartcasting checks on its instances (like
TextView::class.java
in my example). This would require me to make my function generic to benefit from this.
a

arekolek

08/11/2018, 9:08 AM
would something like this help?
Copy code
inline fun <reified T : View> factory(clazz: Class<T>, context: Context) = when (clazz) {
    TextView::class.java -> AppCompatTextView(context)
    Button::class.java -> AppCompatButton(context)
    ImageView::class.java -> AppCompatImageView(context)
    EditText::class.java -> AppCompatEditText(context)
    else -> throw RuntimeException()
} as T
l

louiscad

08/11/2018, 9:10 AM
@arekolek Nope because there is no smart cast, which means you can return
Any?
where a
TextView
or other specific type was expected
a

arekolek

08/11/2018, 9:15 AM
wouldn’t that fail at the
as T
point?
l

louiscad

08/11/2018, 9:17 AM
Yes, but it happens at runtime, not compile time, and I already check the type was what was requested in the caller code
Here's the first issue to allow
when
on reified types https://youtrack.jetbrains.com/issue/KT-26048
Here's the second issue to allow
reified
on non inline functions that have a
Class
or
KClass
parameter: https://youtrack.jetbrains.com/issue/KT-26049
a

Andreas Sinz

08/11/2018, 9:40 AM
is
TextView
the same class that
AppCompatTextView
returns?
l

louiscad

08/11/2018, 9:44 AM
AppCompatTextView
is a
TextView
a

Andreas Sinz

08/11/2018, 9:48 AM
ah ok
and the second question: How does the reification work on the JVM without inlining?
l

louiscad

08/11/2018, 9:55 AM
By getting the type from the class parameter
a

Andreas Sinz

08/11/2018, 10:36 AM
but at runtime the generic type is removed
l

louiscad

08/11/2018, 4:43 PM
It's passed as a parameter (
Class<V>
)
By the way, I found a way to make reified type parameters resuscitate at runtime, it's puzzling me that it can work. I'll post link to the code later
3 Views