Prettify code in 'reflection.jvm'

Use stdlib instead of hand-written hacks, fix some warnings and unneeded !!
This commit is contained in:
Alexander Udalov
2014-11-12 15:21:19 +03:00
parent eced3003ad
commit 9c5bcdc72a
9 changed files with 25 additions and 51 deletions
@@ -26,10 +26,10 @@ enum class KClassOrigin {
FOREIGN FOREIGN
} }
private val KOTLIN_CLASS_ANNOTATION_CLASS = javaClassOf<KotlinClass>() private val KOTLIN_CLASS_ANNOTATION_CLASS = javaClass<KotlinClass>()
private val KOTLIN_SYNTHETIC_CLASS_ANNOTATION_CLASS = javaClassOf<KotlinSyntheticClass>() private val KOTLIN_SYNTHETIC_CLASS_ANNOTATION_CLASS = javaClass<KotlinSyntheticClass>()
class KClassImpl<T>(val jClass: Class<T>, isKnownToBeKotlin: Boolean) : KClass<T> { class KClassImpl<T>(val jClass: Class<T>, isKnownToBeKotlin: Boolean = false) : KClass<T> {
// TODO: write metadata to local classes // TODO: write metadata to local classes
private val origin: KClassOrigin = private val origin: KClassOrigin =
if (isKnownToBeKotlin || if (isKnownToBeKotlin ||
@@ -44,7 +44,7 @@ class KClassImpl<T>(val jClass: Class<T>, isKnownToBeKotlin: Boolean) : KClass<T
} }
fun memberProperty(name: String): KMemberProperty<T, *> = fun memberProperty(name: String): KMemberProperty<T, *> =
if (origin identityEquals KClassOrigin.KOTLIN) { if (origin === KClassOrigin.KOTLIN) {
KMemberPropertyImpl<T, Any>(name, this) KMemberPropertyImpl<T, Any>(name, this)
} }
else { else {
@@ -52,7 +52,7 @@ class KClassImpl<T>(val jClass: Class<T>, isKnownToBeKotlin: Boolean) : KClass<T
} }
fun mutableMemberProperty(name: String): KMutableMemberProperty<T, *> = fun mutableMemberProperty(name: String): KMutableMemberProperty<T, *> =
if (origin identityEquals KClassOrigin.KOTLIN) { if (origin === KClassOrigin.KOTLIN) {
KMutableMemberPropertyImpl<T, Any>(name, this) KMutableMemberPropertyImpl<T, Any>(name, this)
} }
else { else {
@@ -19,5 +19,5 @@ package kotlin.reflect.jvm.internal
import java.io.Serializable import java.io.Serializable
public abstract class KMemberFunctionImpl<in T, out R> : Serializable { public abstract class KMemberFunctionImpl<in T, out R> : Serializable {
override fun toString() = "${(this as Object).getClass().getGenericInterfaces()[0]}" override fun toString() = "${javaClass.getGenericInterfaces().first()}"
} }
@@ -75,7 +75,7 @@ class KMutableMemberPropertyImpl<T : Any, R>(
{ {
try { try {
val returnType = if (getter != null) getter.getReturnType() else field!!.getType() val returnType = if (getter != null) getter.getReturnType() else field!!.getType()
setter = owner.jClass.getMaybeDeclaredMethod(setterName(name), returnType!!) setter = owner.jClass.getMaybeDeclaredMethod(setterName(name), returnType)
} }
catch (e: NoSuchMethodException) { catch (e: NoSuchMethodException) {
if (field == null) throw NoSuchPropertyException(e) if (field == null) throw NoSuchPropertyException(e)
@@ -19,7 +19,7 @@ package kotlin.reflect.jvm.internal
import kotlin.reflect.KPackage import kotlin.reflect.KPackage
import kotlin.jvm.internal.KotlinPackage import kotlin.jvm.internal.KotlinPackage
private val KOTLIN_PACKAGE_ANNOTATION_CLASS = javaClassOf<KotlinPackage>() private val KOTLIN_PACKAGE_ANNOTATION_CLASS = javaClass<KotlinPackage>()
class KPackageImpl(val jClass: Class<*>) : KPackage { class KPackageImpl(val jClass: Class<*>) : KPackage {
override fun equals(other: Any?): Boolean = override fun equals(other: Any?): Boolean =
@@ -28,22 +28,11 @@ class KPackageImpl(val jClass: Class<*>) : KPackage {
override fun hashCode(): Int = override fun hashCode(): Int =
jClass.hashCode() jClass.hashCode()
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
override fun toString(): String { override fun toString(): String {
val name = jClass.getName() as java.lang.String val name = jClass.getName()
return if (jClass.isAnnotationPresent(KOTLIN_PACKAGE_ANNOTATION_CLASS)) { return "package " + if (jClass.isAnnotationPresent(KOTLIN_PACKAGE_ANNOTATION_CLASS)) {
// Cast to Any is needed to suppress the error: "Operator '==' cannot be applied to 'java.lang.String' and 'kotlin.String'" if (name == "_DefaultPackage") "<default>" else name.substringBeforeLast(".")
if ((name : Any) == "_DefaultPackage") {
"package <default>"
}
else {
val lastDot = name.lastIndexOf(".")
if (lastDot >= 0) {
"package ${name.substring(0, lastDot)}"
}
else "package $name"
}
} }
else "package $name" else name
} }
} }
@@ -60,7 +60,7 @@ class KMutableTopLevelExtensionPropertyImpl<T, R>(
receiverClass: Class<T> receiverClass: Class<T>
) : KMutableTopLevelExtensionProperty<T, R>, KMutablePropertyImpl<R>, KTopLevelExtensionPropertyImpl<T, R>(name, owner, receiverClass) { ) : KMutableTopLevelExtensionProperty<T, R>, KMutablePropertyImpl<R>, KTopLevelExtensionPropertyImpl<T, R>(name, owner, receiverClass) {
override val setter: Method = try { override val setter: Method = try {
owner.jClass.getMethod(setterName(name), receiverClass, getter.getReturnType()!!) owner.jClass.getMethod(setterName(name), receiverClass, getter.getReturnType())
} }
catch (e: NoSuchMethodException) { catch (e: NoSuchMethodException) {
throw NoSuchPropertyException(e) throw NoSuchPropertyException(e)
@@ -79,9 +79,8 @@ class KMutableTopLevelExtensionPropertyImpl<T, R>(
"var ${mapJavaClassToKotlin(receiverClass.getName())}.$name" "var ${mapJavaClassToKotlin(receiverClass.getName())}.$name"
} }
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
private fun mapJavaClassToKotlin(name: String): String { private fun mapJavaClassToKotlin(name: String): String {
if (Character.isLowerCase(name[0])) { if (name[0].isLowerCase()) {
return when (name) { return when (name) {
"boolean" -> "kotlin.Boolean" "boolean" -> "kotlin.Boolean"
"char" -> "kotlin.Char" "char" -> "kotlin.Char"
@@ -95,8 +94,8 @@ private fun mapJavaClassToKotlin(name: String): String {
} }
} }
if (name[0] == '[') { if (name[0] == '[') {
val element = (name as java.lang.String).substring(1) as java.lang.String val element = name.substring(1)
return when (element.charAt(0)) { return when (element[0]) {
'Z' -> "kotlin.BooleanArray" 'Z' -> "kotlin.BooleanArray"
'C' -> "kotlin.CharArray" 'C' -> "kotlin.CharArray"
'B' -> "kotlin.ByteArray" 'B' -> "kotlin.ByteArray"
@@ -106,7 +105,7 @@ private fun mapJavaClassToKotlin(name: String): String {
'J' -> "kotlin.LongArray" 'J' -> "kotlin.LongArray"
'D' -> "kotlin.DoubleArray" 'D' -> "kotlin.DoubleArray"
'L' -> "kotlin.Array<${mapJavaClassToKotlin(element.substring(1, element.length() - 1))}>" 'L' -> "kotlin.Array<${mapJavaClassToKotlin(element.substring(1, element.length() - 1))}>"
else -> "kotlin.Array<${mapJavaClassToKotlin(element as kotlin.String)}>" else -> "kotlin.Array<${mapJavaClassToKotlin(element)}>"
} }
} }
return name return name
@@ -59,7 +59,7 @@ class KMutableTopLevelVariableImpl<R>(
owner: KPackageImpl owner: KPackageImpl
) : KMutableTopLevelVariable<R>, KMutableVariableImpl<R>, KTopLevelVariableImpl<R>(name, owner) { ) : KMutableTopLevelVariable<R>, KMutableVariableImpl<R>, KTopLevelVariableImpl<R>(name, owner) {
override val setter: Method = try { override val setter: Method = try {
owner.jClass.getMethod(setterName(name), getter.getReturnType()!!) owner.jClass.getMethod(setterName(name), getter.getReturnType())
} }
catch (e: NoSuchMethodException) { catch (e: NoSuchMethodException) {
throw NoSuchPropertyException(e) throw NoSuchPropertyException(e)
@@ -42,7 +42,7 @@ fun <T> foreignKotlinClass(jClass: Class<T>): KClassImpl<T> {
for (ref in cached) { for (ref in cached) {
val kClass = ref.get() val kClass = ref.get()
if (kClass?.jClass == jClass) { if (kClass?.jClass == jClass) {
return kClass!! return kClass
} }
} }
@@ -53,13 +53,13 @@ fun <T> foreignKotlinClass(jClass: Class<T>): KClassImpl<T> {
val newArray = arrayOfNulls<WeakReference<KClassImpl<*>>>(size + 1) val newArray = arrayOfNulls<WeakReference<KClassImpl<*>>>(size + 1)
// Don't use Arrays.copyOf because it works reflectively // Don't use Arrays.copyOf because it works reflectively
System.arraycopy(cached, 0, newArray, 0, size) System.arraycopy(cached, 0, newArray, 0, size)
val newKClass = KClassImpl(jClass, false) val newKClass = KClassImpl(jClass)
newArray[size] = WeakReference(newKClass) newArray[size] = WeakReference(newKClass)
FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, newArray) FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, newArray)
return newKClass return newKClass
} }
val newKClass = KClassImpl(jClass, false) val newKClass = KClassImpl(jClass)
FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, WeakReference(newKClass)) FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, WeakReference(newKClass))
return newKClass return newKClass
} }
@@ -17,29 +17,16 @@
package kotlin.reflect.jvm.internal package kotlin.reflect.jvm.internal
import java.lang.reflect.Method import java.lang.reflect.Method
import kotlin.jvm.internal.Intrinsic
// TODO: use stdlib?
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
private fun String.capitalizeWithJavaBeanConvention(): String { private fun String.capitalizeWithJavaBeanConvention(): String {
// The code is a bit crooked because otherwise there are overload resolution ambiguities caused by the fact if (length() > 1 && Character.isUpperCase(this[1])) return this
// that we compile it with the built-ins both in source and as a compiled library return Character.toUpperCase(this[0]) + substring(1, length())
val l = length()
if (l > 1 && Character.isUpperCase(get(1))) return this
val first = get(0)
this as java.lang.String
return "" + Character.toUpperCase(first) + substring(1, l)
} }
private fun getterName(propertyName: String): String = "get" + propertyName.capitalizeWithJavaBeanConvention() private fun getterName(propertyName: String): String = "get" + propertyName.capitalizeWithJavaBeanConvention()
private fun setterName(propertyName: String): String = "set" + propertyName.capitalizeWithJavaBeanConvention() private fun setterName(propertyName: String): String = "set" + propertyName.capitalizeWithJavaBeanConvention()
// A local copy of javaClass() from stdlib is needed because there's no dependency on stdlib in runtime.jvm
[Intrinsic("kotlin.javaClass.function")]
fun <reified T> javaClassOf(): Class<T> = throw UnsupportedOperationException()
private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes: Class<*>): Method { private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes: Class<*>): Method {
try { try {
return getMethod(name, *parameterTypes) return getMethod(name, *parameterTypes)
@@ -61,7 +61,7 @@ public val KMemberProperty<*, *>.javaField: Field?
// TODO: getstatic $kotlinClass or go to foreignKClasses // TODO: getstatic $kotlinClass or go to foreignKClasses
public val <T> Class<T>.kotlin: KClass<T> public val <T> Class<T>.kotlin: KClass<T>
get() = KClassImpl(this, false) get() = KClassImpl(this)
// TODO: getstatic $kotlinPackage // TODO: getstatic $kotlinPackage
public val Class<*>.kotlinPackage: KPackage public val Class<*>.kotlinPackage: KPackage
@@ -71,7 +71,7 @@ public val Class<*>.kotlinPackage: KPackage
public val Field.kotlin: KProperty<*> public val Field.kotlin: KProperty<*>
get() { get() {
val clazz = getDeclaringClass() val clazz = getDeclaringClass()
val name = getName()!! val name = getName()
val modifiers = getModifiers() val modifiers = getModifiers()
val static = Modifier.isStatic(modifiers) val static = Modifier.isStatic(modifiers)
val final = Modifier.isFinal(modifiers) val final = Modifier.isFinal(modifiers)
@@ -84,4 +84,3 @@ public val Field.kotlin: KProperty<*>
return if (final) Reflection.memberProperty(name, kClass) else Reflection.mutableMemberProperty(name, kClass) return if (final) Reflection.memberProperty(name, kClass) else Reflection.mutableMemberProperty(name, kClass)
} }
} }