-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JVM] generic array type to TypeToken #4
Conversation
internal class JVMGenericArrayTypeToken<T>(private val trueType: GenericArrayType) : JVMAbstractTypeToken<T>() { | ||
override val jvmType: Type = trueType.genericComponentType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why???
jvmType is supposed to return the JVM type representation of this type token.
This obviously breaks the contract, as it will return the JVM type of the array component.
get() = when (jvmType) { | ||
is Class<*> -> jvmType | ||
is ParameterizedType -> jvmType.rawClass | ||
else -> null | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
Should be:
private val rawType: Class<*>? | |
get() = when (jvmType) { | |
is Class<*> -> jvmType | |
is ParameterizedType -> jvmType.rawClass | |
else -> null | |
} | |
private val rawType: Class<*>? | |
get() { | |
val componentClass = typeToken(trueType.genericComponentType).getRaw().jvmType | |
return java.lang.reflect.Array.newInstance(componentClass, 0).javaClass | |
} |
when (jvmType) { | ||
is Class<*> -> jvmType.typeParameters?.map { typeToken(it.bounds[0]) }?.toTypedArray() ?: emptyArray() | ||
is ParameterizedType -> jvmType.actualTypeArguments.map { typeToken(it) }.toTypedArray() | ||
else -> emptyArray() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because you're using jvmType, you are not returning the generic params of the Array, but of its component.
You should simply return the component type.
@Suppress("UNCHECKED_CAST") | ||
override fun isWildcard(): Boolean { | ||
val realType = trueType as? ParameterizedType ?: return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trueType
is GenericArrayType
. It can never be ParameterizedType
.
You need to check that the array's genericComponentType
isn't wildcard.
is ParameterizedType -> JVMParameterizedTypeToken<Any>(jvmType) | ||
else -> null | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still no.
You are returning the parent of the component.
The parent of Array
is just Any
.
// Test typeToken of GenericArrayType -> Java primitive array | ||
assertEquals(Byte::class.java, typeToken(GenericArrayType { java.lang.Byte.TYPE }).jvmType) | ||
assertEquals(Int::class.java, typeToken(GenericArrayType { Integer.TYPE }).jvmType) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There needs to be more tests.
How do you represent a generic array type using erased ?
We need a way to express the type Array<List<String>>
using erased. Maybe create an erasedArray
function?
There need to be tests that validates that:
assertEquals(generic<Array<List<String>>>, erasedArray(erasedComp(List::class, String::class)))
By the way, there is absolutely no reason those tests are JVM only.
assertEquals(List::class.java, (generic<Array<List<String>>>().getRaw() as JVMClassTypeToken).jvmType) | ||
assertEquals(List::class.java, (generic<Array<List<String>>>().jvmType as ParameterizedType).rawType) | ||
// Test generic parameters (when Array<ParameterizedType>) | ||
assertEquals(String::class.java, generic<Array<List<String>>>().getGenericParameters()[0].jvmType) | ||
assertEquals(String::class.java, ((generic<Array<List<String>>>().jvmType as ParameterizedType).actualTypeArguments[0] as WildcardType).upperBounds[0]) | ||
// Test typeToken of GenericArrayType -> Java primitive array | ||
assertEquals(Byte::class.java, typeToken(GenericArrayType { java.lang.Byte.TYPE }).jvmType) | ||
assertEquals(Int::class.java, typeToken(GenericArrayType { Integer.TYPE }).jvmType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are plainly incorrect.
a02b034
to
422ec3c
Compare
No description provided.