diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KAnnotatedElementImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KAnnotatedElementImpl.kt deleted file mode 100644 index e40e3521b9e..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KAnnotatedElementImpl.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.annotations.Annotated -import org.jetbrains.kotlin.load.java.components.RuntimeSourceElementFactory -import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaAnnotation -import org.jetbrains.kotlin.load.kotlin.reflect.ReflectAnnotationSource -import kotlin.reflect.KAnnotatedElement - -internal interface KAnnotatedElementImpl : KAnnotatedElement { - val annotated: Annotated - - override val annotations: List - get() = annotated.annotations.mapNotNull { - val source = it.source - when (source) { - is ReflectAnnotationSource -> { - source.annotation - } - is RuntimeSourceElementFactory.RuntimeSourceElement -> { - (source.javaElement as? ReflectJavaAnnotation)?.annotation - } - else -> null - } - } -} diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt index bdd7bb165aa..1dd6f36bca5 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt @@ -18,13 +18,12 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.annotations.Annotated import java.lang.reflect.Type import java.util.* import kotlin.reflect.* import kotlin.reflect.jvm.javaType -internal abstract class KCallableImpl : KCallable, KAnnotatedElementImpl { +internal abstract class KCallableImpl : KCallable { abstract val descriptor: CallableMemberDescriptor abstract val caller: FunctionCaller<*> @@ -33,35 +32,47 @@ internal abstract class KCallableImpl : KCallable, KAnnotatedElementIm abstract val container: KDeclarationContainerImpl - override val annotated: Annotated get() = descriptor + private val annotations_ = ReflectProperties.lazySoft { descriptor.computeAnnotations() } - override val parameters: List - get() { - val descriptor = descriptor - val result = ArrayList() - var index = 0 + override val annotations: List get() = annotations_() - if (descriptor.dispatchReceiverParameter != null) { - result.add(KParameterImpl(this, index++, KParameter.Kind.INSTANCE) { descriptor.dispatchReceiverParameter!! }) - } + private val parameters_ = ReflectProperties.lazySoft { + val descriptor = descriptor + val result = ArrayList() + var index = 0 - if (descriptor.extensionReceiverParameter != null) { - result.add(KParameterImpl(this, index++, KParameter.Kind.EXTENSION_RECEIVER) { descriptor.extensionReceiverParameter!! }) - } - - for (i in descriptor.valueParameters.indices) { - result.add(KParameterImpl(this, index++, KParameter.Kind.VALUE) { descriptor.valueParameters[i] }) - } - - result.trimToSize() - return result + if (descriptor.dispatchReceiverParameter != null) { + result.add(KParameterImpl(this, index++, KParameter.Kind.INSTANCE) { descriptor.dispatchReceiverParameter!! }) } + if (descriptor.extensionReceiverParameter != null) { + result.add(KParameterImpl(this, index++, KParameter.Kind.EXTENSION_RECEIVER) { descriptor.extensionReceiverParameter!! }) + } + + for (i in descriptor.valueParameters.indices) { + result.add(KParameterImpl(this, index++, KParameter.Kind.VALUE) { descriptor.valueParameters[i] }) + } + + result.trimToSize() + result + } + + override val parameters: List + get() = parameters_() + + private val returnType_ = ReflectProperties.lazySoft { + KTypeImpl(descriptor.returnType!!) { caller.returnType } + } + override val returnType: KType - get() = KTypeImpl(descriptor.returnType!!) { caller.returnType } + get() = returnType_() + + private val typeParameters_ = ReflectProperties.lazySoft { + descriptor.typeParameters.map(::KTypeParameterImpl) + } override val typeParameters: List - get() = descriptor.typeParameters.map(::KTypeParameterImpl) + get() = typeParameters_() override val visibility: KVisibility? get() = descriptor.visibility.toKVisibility() @@ -134,15 +145,15 @@ internal abstract class KCallableImpl : KCallable, KAnnotatedElementIm private fun defaultPrimitiveValue(type: Type): Any? = if (type is Class<*> && type.isPrimitive) { when (type) { - java.lang.Boolean.TYPE -> false - java.lang.Character.TYPE -> 0.toChar() - java.lang.Byte.TYPE -> 0.toByte() - java.lang.Short.TYPE -> 0.toShort() - java.lang.Integer.TYPE -> 0 - java.lang.Float.TYPE -> 0f - java.lang.Long.TYPE -> 0L - java.lang.Double.TYPE -> 0.0 - java.lang.Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal") + Boolean::class.java -> false + Char::class.java -> 0.toChar() + Byte::class.java -> 0.toByte() + Short::class.java -> 0.toShort() + Int::class.java -> 0 + Float::class.java -> 0f + Long::class.java -> 0L + Double::class.java -> 0.0 + Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal") else -> throw UnsupportedOperationException("Unknown primitive: $type") } } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt index 710a98cf276..f44ba6122a7 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt @@ -18,7 +18,6 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.builtins.CompanionObjectMapping import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.structure.reflect.functionClassArity @@ -35,8 +34,7 @@ import kotlin.reflect.* import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.DECLARED import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.INHERITED -internal class KClassImpl(override val jClass: Class) : - KDeclarationContainerImpl(), KClass, KClassifierImpl, KAnnotatedElementImpl { +internal class KClassImpl(override val jClass: Class) : KDeclarationContainerImpl(), KClass, KClassifierImpl { inner class Data : KDeclarationContainerImpl.Data() { val descriptor: ClassDescriptor by ReflectProperties.lazySoft { val classId = classId @@ -49,6 +47,8 @@ internal class KClassImpl(override val jClass: Class) : descriptor ?: reportUnresolvedClass() } + val annotations: List by ReflectProperties.lazySoft { descriptor.computeAnnotations() } + val simpleName: String? by ReflectProperties.lazySoft { if (jClass.isAnonymousClass) return@lazySoft null @@ -156,7 +156,7 @@ internal class KClassImpl(override val jClass: Class) : override val descriptor: ClassDescriptor get() = data().descriptor - override val annotated: Annotated get() = descriptor + override val annotations: List get() = data().annotations private val classId: ClassId get() = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass) diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt index c2410ff1806..df1f0b963bf 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt @@ -40,7 +40,7 @@ internal class KFunctionImpl private constructor( container, descriptor.name.asString(), RuntimeTypeMapper.mapSignature(descriptor).asString(), descriptor ) - override val descriptor: FunctionDescriptor by ReflectProperties.lazySoft(descriptorInitialValue) { + override val descriptor: FunctionDescriptor by ReflectProperties.lazySoft(descriptorInitialValue) { container.findFunctionDescriptor(name, signature) } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt index 73b411b2a96..3407153591b 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt @@ -18,7 +18,6 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import kotlin.reflect.KParameter import kotlin.reflect.KType @@ -28,10 +27,10 @@ internal class KParameterImpl( override val index: Int, override val kind: KParameter.Kind, computeDescriptor: () -> ParameterDescriptor -) : KParameter, KAnnotatedElementImpl { +) : KParameter { private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor) - override val annotated: Annotated get() = descriptor + override val annotations: List by ReflectProperties.lazySoft { descriptor.computeAnnotations() } override val name: String? get() { val valueParameter = descriptor as? ValueParameterDescriptor ?: return null diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt index ed068d2d036..0a21124546f 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt @@ -79,7 +79,7 @@ internal abstract class KPropertyImpl private constructor( override abstract val getter: Getter - private val descriptor_ = ReflectProperties.lazySoft(descriptorInitialValue) { + private val descriptor_ = ReflectProperties.lazySoft(descriptorInitialValue) { container.findPropertyDescriptor(name, signature) } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeImpl.kt index 7614408b92c..9cd2aeea301 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeImpl.kt @@ -42,8 +42,7 @@ internal class KTypeImpl( ) : KType { internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType) - override val classifier: KClassifier? - get() = convert(type) + override val classifier: KClassifier? by ReflectProperties.lazySoft { convert(type) } private fun convert(type: KotlinType): KClassifier? { val descriptor = type.constructor.declarationDescriptor @@ -71,47 +70,46 @@ internal class KTypeImpl( } } - override val arguments: List - get() { - val typeArguments = type.arguments - if (typeArguments.isEmpty()) return emptyList() + override val arguments: List by ReflectProperties.lazySoft arguments@ { + val typeArguments = type.arguments + if (typeArguments.isEmpty()) return@arguments emptyList() - val parameterizedTypeArguments by lazy(PUBLICATION) { javaType.parameterizedTypeArguments } + val parameterizedTypeArguments by lazy(PUBLICATION) { javaType.parameterizedTypeArguments } - return typeArguments.mapIndexed { i, typeProjection -> - if (typeProjection.isStarProjection) { - KTypeProjection.STAR - } - else { - val type = KTypeImpl(typeProjection.type) { - val javaType = javaType - when (javaType) { - is Class<*> -> { - // It's either an array or a raw type. - // TODO: return upper bound of the corresponding parameter for a raw type? - if (javaType.isArray) javaType.componentType else Any::class.java - } - is GenericArrayType -> { - if (i != 0) throw KotlinReflectionInternalError("Array type has been queried for a non-0th argument: $this") - javaType.genericComponentType - } - is ParameterizedType -> { - val argument = parameterizedTypeArguments[i] - // In "Foo", the JVM type of the first type argument should be "Bar", not "? extends Bar" - if (argument !is WildcardType) argument - else argument.lowerBounds.firstOrNull() ?: argument.upperBounds.first() - } - else -> throw KotlinReflectionInternalError("Non-generic type has been queried for arguments: $this") + typeArguments.mapIndexed { i, typeProjection -> + if (typeProjection.isStarProjection) { + KTypeProjection.STAR + } + else { + val type = KTypeImpl(typeProjection.type) { + val javaType = javaType + when (javaType) { + is Class<*> -> { + // It's either an array or a raw type. + // TODO: return upper bound of the corresponding parameter for a raw type? + if (javaType.isArray) javaType.componentType else Any::class.java } + is GenericArrayType -> { + if (i != 0) throw KotlinReflectionInternalError("Array type has been queried for a non-0th argument: $this") + javaType.genericComponentType + } + is ParameterizedType -> { + val argument = parameterizedTypeArguments[i] + // In "Foo", the JVM type of the first type argument should be "Bar", not "? extends Bar" + if (argument !is WildcardType) argument + else argument.lowerBounds.firstOrNull() ?: argument.upperBounds.first() + } + else -> throw KotlinReflectionInternalError("Non-generic type has been queried for arguments: $this") } - when (typeProjection.projectionKind) { - Variance.INVARIANT -> KTypeProjection.invariant(type) - Variance.IN_VARIANCE -> KTypeProjection.contravariant(type) - Variance.OUT_VARIANCE -> KTypeProjection.covariant(type) - } + } + when (typeProjection.projectionKind) { + Variance.INVARIANT -> KTypeProjection.invariant(type) + Variance.IN_VARIANCE -> KTypeProjection.contravariant(type) + Variance.OUT_VARIANCE -> KTypeProjection.covariant(type) } } } + } override val isMarkedNullable: Boolean get() = type.isMarkedNullable diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt index 691f6563853..56e1f50c539 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt @@ -26,12 +26,13 @@ internal class KTypeParameterImpl(override val descriptor: TypeParameterDescript override val name: String get() = descriptor.name.asString() - override val upperBounds: List - get() = descriptor.upperBounds.map { kotlinType -> + override val upperBounds: List by ReflectProperties.lazySoft { + descriptor.upperBounds.map { kotlinType -> KTypeImpl(kotlinType) { TODO("Java type is not yet supported for type parameters: $descriptor") } } + } override val variance: KVariance get() = when (descriptor.variance) { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt index 9a9f0d5c43d..1e63908d6c4 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt @@ -19,11 +19,14 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.load.java.components.RuntimeSourceElementFactory import org.jetbrains.kotlin.load.java.reflect.tryLoadClass +import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaAnnotation import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaClass import org.jetbrains.kotlin.load.java.structure.reflect.safeClassLoader import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement +import org.jetbrains.kotlin.load.kotlin.reflect.ReflectAnnotationSource import org.jetbrains.kotlin.load.kotlin.reflect.ReflectKotlinClass import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.platform.JavaToKotlinClassMap @@ -85,6 +88,16 @@ internal fun Visibility.toKVisibility(): KVisibility? = else -> null } +internal fun Annotated.computeAnnotations(): List = + annotations.mapNotNull { + val source = it.source + when (source) { + is ReflectAnnotationSource -> source.annotation + is RuntimeSourceElementFactory.RuntimeSourceElement -> (source.javaElement as? ReflectJavaAnnotation)?.annotation + else -> null + } + } + // TODO: wrap other exceptions internal inline fun reflectionCall(block: () -> R): R = try {