Support mapping between Java and Kotlin reflection objects

This commit is contained in:
Alexander Udalov
2014-06-20 19:22:02 +04:00
parent c575ad9fb0
commit 704de8992e
33 changed files with 434 additions and 93 deletions
@@ -0,0 +1,22 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.jvm.internal
import java.lang.annotation.*
Retention(RetentionPolicy.RUNTIME)
public annotation class Intrinsic(val value: String)
@@ -17,6 +17,8 @@
package kotlin.reflect.jvm.internal
import kotlin.reflect.*
import kotlin.jvm.internal.KotlinClass
import kotlin.jvm.internal.KotlinSyntheticClass
enum class KClassOrigin {
BUILT_IN
@@ -24,8 +26,8 @@ enum class KClassOrigin {
FOREIGN
}
private val KOTLIN_CLASS_ANNOTATION_CLASS = Class.forName("kotlin.jvm.internal.KotlinClass") as Class<Annotation>
private val KOTLIN_SYNTHETIC_CLASS_ANNOTATION_CLASS = Class.forName("kotlin.jvm.internal.KotlinSyntheticClass") as Class<Annotation>
private val KOTLIN_CLASS_ANNOTATION_CLASS = javaClass<KotlinClass>()
private val KOTLIN_SYNTHETIC_CLASS_ANNOTATION_CLASS = javaClass<KotlinSyntheticClass>()
class KClassImpl<out T>(val jClass: Class<T>) : KClass<T> {
// TODO: write metadata to local classes
@@ -15,8 +15,7 @@
*/
package kotlin.reflect.jvm.internal
import kotlin.reflect.*
class KPackageImpl(
val jClass: Class<*>
) : KPackage
import kotlin.reflect.KPackage
class KPackageImpl(val jClass: Class<*>) : KPackage
@@ -17,6 +17,7 @@
package kotlin.reflect.jvm.internal
import java.lang.reflect.Method
import kotlin.jvm.internal.Intrinsic
// TODO: use stdlib?
suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
@@ -34,6 +35,11 @@ private fun getterName(propertyName: String): String = "get" + propertyName.capi
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> javaClass(): Class<T> = throw UnsupportedOperationException()
private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes: Class<*>): Method {
try {
return getMethod(name, *parameterTypes)
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.reflect.jvm
import java.lang.reflect.*
import kotlin.reflect.*
import kotlin.reflect.jvm.internal.*
// Kotlin reflection -> Java reflection
public val <T> KClass<T>.java: Class<T>
get() = (this as KClassImpl<T>).jClass
public val KPackage.javaFacade: Class<*>
get() = (this as KPackageImpl).jClass
public val KProperty<*>.javaGetter: Method?
get() = (this as? KPropertyImpl<*>)?.getter
public val KMutableProperty<*>.javaSetter: Method?
get() = (this as? KMutablePropertyImpl<*>)?.setter
// TODO: val KTopLevelVariable<*>.javaField: Field
public val KTopLevelVariable<*>.javaGetter: Method
get() = (this as KTopLevelVariableImpl<*>).getter
public val KMutableTopLevelVariable<*>.javaSetter: Method
get() = (this as KMutableTopLevelVariableImpl<*>).setter
public val KTopLevelExtensionProperty<*, *>.javaGetter: Method
get() = (this as KTopLevelExtensionPropertyImpl<*, *>).getter
public val KMutableTopLevelExtensionProperty<*, *>.javaSetter: Method
get() = (this as KMutableTopLevelExtensionPropertyImpl<*, *>).setter
public val KMemberProperty<*, *>.javaField: Field?
get() = (this as KPropertyImpl<*>).field
// Java reflection -> Kotlin reflection
public val <T> Class<T>.kotlin: KClass<T>
get() = kClass(this)
public val Class<*>.kotlinPackage: KPackage
get() = kPackage(this)
public val Field.kotlin: KProperty<*>
get() {
val clazz = getDeclaringClass()
val name = getName()!!
val modifiers = getModifiers()
val static = Modifier.isStatic(modifiers)
val final = Modifier.isFinal(modifiers)
if (static) {
val kPackage = kPackage(clazz)
return if (final) topLevelVariable(name, kPackage) else mutableTopLevelVariable(name, kPackage)
}
else {
val kClass = kClass(clazz as Class<Any>)
return if (final) kClass.memberProperty(name) else kClass.mutableMemberProperty(name)
}
}