org.pkl.thirdparty.kotlin.reflect.jvm.ReflectJvmMapping.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pkl-tools Show documentation
Show all versions of pkl-tools Show documentation
Fat Jar containing pkl-cli, pkl-codegen-java, pkl-codegen-kotlin, pkl-config-java, pkl-core, pkl-doc, and their shaded third-party dependencies.
/*
* Copyright 2010-2015 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.
*/
@file:JvmName("ReflectJvmMapping")
package org.pkl.thirdparty.kotlin.reflect.jvm
import org.pkl.thirdparty.jetbrains.kotlin.descriptors.runtime.components.ReflectKotlinClass
import org.pkl.thirdparty.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import java.lang.reflect.*
import org.pkl.thirdparty.kotlin.reflect.*
import org.pkl.thirdparty.kotlin.reflect.full.companionObject
import org.pkl.thirdparty.kotlin.reflect.full.functions
import org.pkl.thirdparty.kotlin.reflect.full.memberProperties
import org.pkl.thirdparty.kotlin.reflect.jvm.internal.KPackageImpl
import org.pkl.thirdparty.kotlin.reflect.jvm.internal.KTypeImpl
import org.pkl.thirdparty.kotlin.reflect.jvm.internal.asKCallableImpl
import org.pkl.thirdparty.kotlin.reflect.jvm.internal.asKPropertyImpl
import org.pkl.thirdparty.kotlin.reflect.javaType as stdlibJavaType
// Kotlin reflection -> Java reflection
/**
* Returns a Java [Field] instance corresponding to the backing field of the given property,
* or `null` if the property has no backing field.
*/
val KProperty<*>.javaField: Field?
get() = this.asKPropertyImpl()?.javaField
/**
* Returns a Java [Method] instance corresponding to the getter of the given property,
* or `null` if the property has no getter, for example in case of a simple private `val` in a class.
*/
val KProperty<*>.javaGetter: Method?
get() = getter.javaMethod
/**
* Returns a Java [Method] instance corresponding to the setter of the given mutable property,
* or `null` if the property has no setter, for example in case of a simple private `var` in a class.
*/
val KMutableProperty<*>.javaSetter: Method?
get() = setter.javaMethod
/**
* Returns a Java [Method] instance corresponding to the given Kotlin function,
* or `null` if this function is a constructor or cannot be represented by a Java [Method].
*/
val KFunction<*>.javaMethod: Method?
get() = this.asKCallableImpl()?.caller?.member as? Method
/**
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
* or `null` if this function is not a constructor or cannot be represented by a Java [Constructor].
*/
@Suppress("UNCHECKED_CAST")
val KFunction.javaConstructor: Constructor?
get() = this.asKCallableImpl()?.caller?.member as? Constructor
/**
* Returns a Java [Type] instance corresponding to the given Kotlin type.
* Note that one Kotlin type may correspond to different JVM types depending on where it appears. For example, [Unit] corresponds to
* the JVM class [Unit] when it's the type of a parameter, or to `void` when it's the return type of a function.
*/
val KType.javaType: Type
@OptIn(ExperimentalStdlibApi::class)
get() = (this as KTypeImpl).javaType ?: stdlibJavaType
// Java reflection -> Kotlin reflection
/**
* Returns a [KProperty] instance corresponding to the given Java [Field] instance,
* or `null` if this field cannot be represented by a Kotlin property
* (for example, if it is a synthetic field).
*/
val Field.kotlinProperty: KProperty<*>?
get() {
if (isSynthetic) return null
// TODO: optimize (search by name)
val kotlinPackage = getKPackage()
if (kotlinPackage != null) {
return kotlinPackage.members.filterIsInstance>().firstOrNull { it.javaField == this }
}
return declaringClass.kotlin.memberProperties.firstOrNull { it.javaField == this }
}
private fun Member.getKPackage(): KDeclarationContainer? =
when (ReflectKotlinClass.create(declaringClass)?.classHeader?.kind) {
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ->
KPackageImpl(declaringClass)
else -> null
}
/**
* Returns a [KFunction] instance corresponding to the given Java [Method] instance,
* or `null` if this method cannot be represented by a Kotlin function.
*/
val Method.kotlinFunction: KFunction<*>?
get() {
if (Modifier.isStatic(modifiers)) {
val kotlinPackage = getKPackage()
if (kotlinPackage != null) {
return kotlinPackage.members.filterIsInstance>().firstOrNull { it.javaMethod == this }
}
// For static bridge method generated for a @JvmStatic function in the companion object, also try to find the latter
val companion = declaringClass.kotlin.companionObject
if (companion != null) {
companion.functions.firstOrNull {
val m = it.javaMethod
m != null && m.name == this.name &&
m.parameterTypes.contentEquals(this.parameterTypes) && m.returnType == this.returnType
}?.let { return it }
}
}
return declaringClass.kotlin.functions.firstOrNull { it.javaMethod == this }
}
/**
* Returns a [KFunction] instance corresponding to the given Java [Constructor] instance,
* or `null` if this constructor cannot be represented by a Kotlin function
* (for example, if it is a synthetic constructor).
*/
val Constructor.kotlinFunction: KFunction?
get() {
return declaringClass.kotlin.constructors.firstOrNull { it.javaConstructor == this }
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy