kotlin.reflect.jvm.internal.KPropertyImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-reflect Show documentation
Show all versions of kotlin-reflect Show documentation
Kotlin Full Reflection Library
/*
* 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.
*/
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.reflect.ReflectKotlinClass
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.TypeUtils
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import kotlin.reflect.KMutableProperty
import kotlin.reflect.KProperty
internal interface KPropertyImpl : KProperty, KCallableImpl {
val javaField: Field?
val container: KDeclarationContainerImpl
val signature: String
override val getter: Getter
override val descriptor: PropertyDescriptor
override val name: String get() = descriptor.name.asString()
override val caller: FunctionCaller<*> get() = getter.caller
override val defaultCaller: FunctionCaller<*>? get() = getter.defaultCaller
abstract class Accessor : KProperty.Accessor {
abstract override val property: KPropertyImpl
internal abstract val descriptor: PropertyAccessorDescriptor
}
abstract class Getter : Accessor(), KProperty.Getter, KCallableImpl {
override val name: String get() = ""
override val descriptor: PropertyGetterDescriptor by ReflectProperties.lazySoft {
// TODO: default getter created this way won't have any source information
property.descriptor.getter ?: DescriptorFactory.createDefaultGetter(property.descriptor, Annotations.EMPTY)
}
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
computeCallerForAccessor(isGetter = true)
}
override val defaultCaller: FunctionCaller<*>? get() = null
}
}
internal interface KMutablePropertyImpl : KMutableProperty, KPropertyImpl {
override val setter: Setter
abstract class Setter : KPropertyImpl.Accessor(), KMutableProperty.Setter, KCallableImpl {
abstract override val property: KMutablePropertyImpl
override val name: String get() = ""
override val descriptor: PropertySetterDescriptor by ReflectProperties.lazySoft {
// TODO: default setter created this way won't have any source information
property.descriptor.setter ?: DescriptorFactory.createDefaultSetter(property.descriptor, Annotations.EMPTY)
}
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft {
computeCallerForAccessor(isGetter = false)
}
override val defaultCaller: FunctionCaller<*>? get() = null
}
}
private fun KPropertyImpl.Accessor<*>.computeCallerForAccessor(isGetter: Boolean): FunctionCaller<*> {
fun isInsideClassCompanionObject(): Boolean {
val possibleCompanionObject = property.descriptor.containingDeclaration
if (DescriptorUtils.isCompanionObject(possibleCompanionObject) && !DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)) {
return true
}
return false
}
fun isJvmStaticProperty() =
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
fun isNotNullProperty() =
!TypeUtils.isNullableType(property.descriptor.type)
fun computeFieldCaller(field: Field): FunctionCaller = when {
isInsideClassCompanionObject() -> {
val containingDeclaration = descriptor.containingDeclaration as ClassDescriptor
val sourceElement = containingDeclaration.source as KotlinJvmBinarySourceElement
val klass = (sourceElement.binaryClass as ReflectKotlinClass).klass
if (isGetter) FunctionCaller.ClassCompanionFieldGetter(field, klass)
else FunctionCaller.ClassCompanionFieldSetter(field, klass)
}
!Modifier.isStatic(field.modifiers) ->
if (isGetter) FunctionCaller.InstanceFieldGetter(field)
else FunctionCaller.InstanceFieldSetter(field, isNotNullProperty())
isJvmStaticProperty() ->
if (isGetter) FunctionCaller.JvmStaticInObjectFieldGetter(field)
else FunctionCaller.JvmStaticInObjectFieldSetter(field, isNotNullProperty())
else ->
if (isGetter) FunctionCaller.StaticFieldGetter(field)
else FunctionCaller.StaticFieldSetter(field, isNotNullProperty())
}
val jvmSignature = RuntimeTypeMapper.mapPropertySignature(property.descriptor)
return when (jvmSignature) {
is JvmPropertySignature.KotlinProperty -> {
val accessorSignature = jvmSignature.signature.run {
when {
isGetter -> if (hasGetter()) getter else null
else -> if (hasSetter()) setter else null
}
}
val accessor = accessorSignature?.let { signature ->
property.container.findMethodBySignature(
jvmSignature.nameResolver.getString(signature.name),
jvmSignature.nameResolver.getString(signature.desc),
Visibilities.isPrivate(descriptor.visibility)
)
}
when {
accessor == null -> computeFieldCaller(property.javaField!!)
!Modifier.isStatic(accessor.modifiers) -> FunctionCaller.InstanceMethod(accessor)
isJvmStaticProperty() -> FunctionCaller.JvmStaticInObject(accessor)
else -> FunctionCaller.StaticMethod(accessor)
}
}
is JvmPropertySignature.JavaField -> {
computeFieldCaller(jvmSignature.field)
}
}
}