Prettify code in 'reflection.jvm'
Use stdlib instead of hand-written hacks, fix some warnings and unneeded !!
This commit is contained in:
@@ -26,10 +26,10 @@ enum class KClassOrigin {
|
||||
FOREIGN
|
||||
}
|
||||
|
||||
private val KOTLIN_CLASS_ANNOTATION_CLASS = javaClassOf<KotlinClass>()
|
||||
private val KOTLIN_SYNTHETIC_CLASS_ANNOTATION_CLASS = javaClassOf<KotlinSyntheticClass>()
|
||||
private val KOTLIN_CLASS_ANNOTATION_CLASS = javaClass<KotlinClass>()
|
||||
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
|
||||
private val origin: KClassOrigin =
|
||||
if (isKnownToBeKotlin ||
|
||||
@@ -44,7 +44,7 @@ class KClassImpl<T>(val jClass: Class<T>, isKnownToBeKotlin: Boolean) : KClass<T
|
||||
}
|
||||
|
||||
fun memberProperty(name: String): KMemberProperty<T, *> =
|
||||
if (origin identityEquals KClassOrigin.KOTLIN) {
|
||||
if (origin === KClassOrigin.KOTLIN) {
|
||||
KMemberPropertyImpl<T, Any>(name, this)
|
||||
}
|
||||
else {
|
||||
@@ -52,7 +52,7 @@ class KClassImpl<T>(val jClass: Class<T>, isKnownToBeKotlin: Boolean) : KClass<T
|
||||
}
|
||||
|
||||
fun mutableMemberProperty(name: String): KMutableMemberProperty<T, *> =
|
||||
if (origin identityEquals KClassOrigin.KOTLIN) {
|
||||
if (origin === KClassOrigin.KOTLIN) {
|
||||
KMutableMemberPropertyImpl<T, Any>(name, this)
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -19,5 +19,5 @@ package kotlin.reflect.jvm.internal
|
||||
import java.io.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 {
|
||||
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) {
|
||||
if (field == null) throw NoSuchPropertyException(e)
|
||||
|
||||
@@ -19,7 +19,7 @@ package kotlin.reflect.jvm.internal
|
||||
import kotlin.reflect.KPackage
|
||||
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 {
|
||||
override fun equals(other: Any?): Boolean =
|
||||
@@ -28,22 +28,11 @@ class KPackageImpl(val jClass: Class<*>) : KPackage {
|
||||
override fun hashCode(): Int =
|
||||
jClass.hashCode()
|
||||
|
||||
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
override fun toString(): String {
|
||||
val name = jClass.getName() as java.lang.String
|
||||
return 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 : Any) == "_DefaultPackage") {
|
||||
"package <default>"
|
||||
}
|
||||
else {
|
||||
val lastDot = name.lastIndexOf(".")
|
||||
if (lastDot >= 0) {
|
||||
"package ${name.substring(0, lastDot)}"
|
||||
}
|
||||
else "package $name"
|
||||
}
|
||||
val name = jClass.getName()
|
||||
return "package " + if (jClass.isAnnotationPresent(KOTLIN_PACKAGE_ANNOTATION_CLASS)) {
|
||||
if (name == "_DefaultPackage") "<default>" else name.substringBeforeLast(".")
|
||||
}
|
||||
else "package $name"
|
||||
else name
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -60,7 +60,7 @@ class KMutableTopLevelExtensionPropertyImpl<T, R>(
|
||||
receiverClass: Class<T>
|
||||
) : KMutableTopLevelExtensionProperty<T, R>, KMutablePropertyImpl<R>, KTopLevelExtensionPropertyImpl<T, R>(name, owner, receiverClass) {
|
||||
override val setter: Method = try {
|
||||
owner.jClass.getMethod(setterName(name), receiverClass, getter.getReturnType()!!)
|
||||
owner.jClass.getMethod(setterName(name), receiverClass, getter.getReturnType())
|
||||
}
|
||||
catch (e: NoSuchMethodException) {
|
||||
throw NoSuchPropertyException(e)
|
||||
@@ -79,9 +79,8 @@ class KMutableTopLevelExtensionPropertyImpl<T, R>(
|
||||
"var ${mapJavaClassToKotlin(receiverClass.getName())}.$name"
|
||||
}
|
||||
|
||||
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
private fun mapJavaClassToKotlin(name: String): String {
|
||||
if (Character.isLowerCase(name[0])) {
|
||||
if (name[0].isLowerCase()) {
|
||||
return when (name) {
|
||||
"boolean" -> "kotlin.Boolean"
|
||||
"char" -> "kotlin.Char"
|
||||
@@ -95,8 +94,8 @@ private fun mapJavaClassToKotlin(name: String): String {
|
||||
}
|
||||
}
|
||||
if (name[0] == '[') {
|
||||
val element = (name as java.lang.String).substring(1) as java.lang.String
|
||||
return when (element.charAt(0)) {
|
||||
val element = name.substring(1)
|
||||
return when (element[0]) {
|
||||
'Z' -> "kotlin.BooleanArray"
|
||||
'C' -> "kotlin.CharArray"
|
||||
'B' -> "kotlin.ByteArray"
|
||||
@@ -106,7 +105,7 @@ private fun mapJavaClassToKotlin(name: String): String {
|
||||
'J' -> "kotlin.LongArray"
|
||||
'D' -> "kotlin.DoubleArray"
|
||||
'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
|
||||
|
||||
@@ -59,7 +59,7 @@ class KMutableTopLevelVariableImpl<R>(
|
||||
owner: KPackageImpl
|
||||
) : KMutableTopLevelVariable<R>, KMutableVariableImpl<R>, KTopLevelVariableImpl<R>(name, owner) {
|
||||
override val setter: Method = try {
|
||||
owner.jClass.getMethod(setterName(name), getter.getReturnType()!!)
|
||||
owner.jClass.getMethod(setterName(name), getter.getReturnType())
|
||||
}
|
||||
catch (e: NoSuchMethodException) {
|
||||
throw NoSuchPropertyException(e)
|
||||
|
||||
@@ -42,7 +42,7 @@ fun <T> foreignKotlinClass(jClass: Class<T>): KClassImpl<T> {
|
||||
for (ref in cached) {
|
||||
val kClass = ref.get()
|
||||
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)
|
||||
// Don't use Arrays.copyOf because it works reflectively
|
||||
System.arraycopy(cached, 0, newArray, 0, size)
|
||||
val newKClass = KClassImpl(jClass, false)
|
||||
val newKClass = KClassImpl(jClass)
|
||||
newArray[size] = WeakReference(newKClass)
|
||||
FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, newArray)
|
||||
return newKClass
|
||||
}
|
||||
|
||||
val newKClass = KClassImpl(jClass, false)
|
||||
val newKClass = KClassImpl(jClass)
|
||||
FOREIGN_K_CLASSES = FOREIGN_K_CLASSES.plus(name, WeakReference(newKClass))
|
||||
return newKClass
|
||||
}
|
||||
|
||||
@@ -17,29 +17,16 @@
|
||||
package kotlin.reflect.jvm.internal
|
||||
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.jvm.internal.Intrinsic
|
||||
|
||||
// TODO: use stdlib?
|
||||
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||
private fun String.capitalizeWithJavaBeanConvention(): String {
|
||||
// The code is a bit crooked because otherwise there are overload resolution ambiguities caused by the fact
|
||||
// that we compile it with the built-ins both in source and as a compiled library
|
||||
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)
|
||||
if (length() > 1 && Character.isUpperCase(this[1])) return this
|
||||
return Character.toUpperCase(this[0]) + substring(1, length())
|
||||
}
|
||||
|
||||
private fun getterName(propertyName: String): String = "get" + 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 {
|
||||
try {
|
||||
return getMethod(name, *parameterTypes)
|
||||
|
||||
@@ -61,7 +61,7 @@ public val KMemberProperty<*, *>.javaField: Field?
|
||||
|
||||
// TODO: getstatic $kotlinClass or go to foreignKClasses
|
||||
public val <T> Class<T>.kotlin: KClass<T>
|
||||
get() = KClassImpl(this, false)
|
||||
get() = KClassImpl(this)
|
||||
|
||||
// TODO: getstatic $kotlinPackage
|
||||
public val Class<*>.kotlinPackage: KPackage
|
||||
@@ -71,7 +71,7 @@ public val Class<*>.kotlinPackage: KPackage
|
||||
public val Field.kotlin: KProperty<*>
|
||||
get() {
|
||||
val clazz = getDeclaringClass()
|
||||
val name = getName()!!
|
||||
val name = getName()
|
||||
val modifiers = getModifiers()
|
||||
val static = Modifier.isStatic(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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user