Cache more stuff in reflection implementation

Delete KAnnotatedElementImpl because it's not possible to make it a class (its
subclasses have other classes in supertypes) to cache annotations in a property
This commit is contained in:
Alexander Udalov
2016-09-08 16:11:23 +03:00
parent 80db0e4b71
commit b9dec41ea0
9 changed files with 101 additions and 120 deletions
@@ -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<Annotation>
get() = annotated.annotations.mapNotNull {
val source = it.source
when (source) {
is ReflectAnnotationSource -> {
source.annotation
}
is RuntimeSourceElementFactory.RuntimeSourceElement -> {
(source.javaElement as? ReflectJavaAnnotation)?.annotation
}
else -> null
}
}
}
@@ -18,13 +18,12 @@ package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import java.lang.reflect.Type import java.lang.reflect.Type
import java.util.* import java.util.*
import kotlin.reflect.* import kotlin.reflect.*
import kotlin.reflect.jvm.javaType import kotlin.reflect.jvm.javaType
internal abstract class KCallableImpl<out R> : KCallable<R>, KAnnotatedElementImpl { internal abstract class KCallableImpl<out R> : KCallable<R> {
abstract val descriptor: CallableMemberDescriptor abstract val descriptor: CallableMemberDescriptor
abstract val caller: FunctionCaller<*> abstract val caller: FunctionCaller<*>
@@ -33,10 +32,11 @@ internal abstract class KCallableImpl<out R> : KCallable<R>, KAnnotatedElementIm
abstract val container: KDeclarationContainerImpl abstract val container: KDeclarationContainerImpl
override val annotated: Annotated get() = descriptor private val annotations_ = ReflectProperties.lazySoft { descriptor.computeAnnotations() }
override val parameters: List<KParameter> override val annotations: List<Annotation> get() = annotations_()
get() {
private val parameters_ = ReflectProperties.lazySoft {
val descriptor = descriptor val descriptor = descriptor
val result = ArrayList<KParameter>() val result = ArrayList<KParameter>()
var index = 0 var index = 0
@@ -54,14 +54,25 @@ internal abstract class KCallableImpl<out R> : KCallable<R>, KAnnotatedElementIm
} }
result.trimToSize() result.trimToSize()
return result result
}
override val parameters: List<KParameter>
get() = parameters_()
private val returnType_ = ReflectProperties.lazySoft {
KTypeImpl(descriptor.returnType!!) { caller.returnType }
} }
override val returnType: KType 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<KTypeParameter> override val typeParameters: List<KTypeParameter>
get() = descriptor.typeParameters.map(::KTypeParameterImpl) get() = typeParameters_()
override val visibility: KVisibility? override val visibility: KVisibility?
get() = descriptor.visibility.toKVisibility() get() = descriptor.visibility.toKVisibility()
@@ -134,15 +145,15 @@ internal abstract class KCallableImpl<out R> : KCallable<R>, KAnnotatedElementIm
private fun defaultPrimitiveValue(type: Type): Any? = private fun defaultPrimitiveValue(type: Type): Any? =
if (type is Class<*> && type.isPrimitive) { if (type is Class<*> && type.isPrimitive) {
when (type) { when (type) {
java.lang.Boolean.TYPE -> false Boolean::class.java -> false
java.lang.Character.TYPE -> 0.toChar() Char::class.java -> 0.toChar()
java.lang.Byte.TYPE -> 0.toByte() Byte::class.java -> 0.toByte()
java.lang.Short.TYPE -> 0.toShort() Short::class.java -> 0.toShort()
java.lang.Integer.TYPE -> 0 Int::class.java -> 0
java.lang.Float.TYPE -> 0f Float::class.java -> 0f
java.lang.Long.TYPE -> 0L Long::class.java -> 0L
java.lang.Double.TYPE -> 0.0 Double::class.java -> 0.0
java.lang.Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal") Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal")
else -> throw UnsupportedOperationException("Unknown primitive: $type") else -> throw UnsupportedOperationException("Unknown primitive: $type")
} }
} }
@@ -18,7 +18,6 @@ package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.builtins.CompanionObjectMapping import org.jetbrains.kotlin.builtins.CompanionObjectMapping
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.structure.reflect.functionClassArity 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.DECLARED
import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.INHERITED import kotlin.reflect.jvm.internal.KDeclarationContainerImpl.MemberBelonginess.INHERITED
internal class KClassImpl<T : Any>(override val jClass: Class<T>) : internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclarationContainerImpl(), KClass<T>, KClassifierImpl {
KDeclarationContainerImpl(), KClass<T>, KClassifierImpl, KAnnotatedElementImpl {
inner class Data : KDeclarationContainerImpl.Data() { inner class Data : KDeclarationContainerImpl.Data() {
val descriptor: ClassDescriptor by ReflectProperties.lazySoft { val descriptor: ClassDescriptor by ReflectProperties.lazySoft {
val classId = classId val classId = classId
@@ -49,6 +47,8 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) :
descriptor ?: reportUnresolvedClass() descriptor ?: reportUnresolvedClass()
} }
val annotations: List<Annotation> by ReflectProperties.lazySoft { descriptor.computeAnnotations() }
val simpleName: String? by ReflectProperties.lazySoft { val simpleName: String? by ReflectProperties.lazySoft {
if (jClass.isAnonymousClass) return@lazySoft null if (jClass.isAnonymousClass) return@lazySoft null
@@ -156,7 +156,7 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) :
override val descriptor: ClassDescriptor get() = data().descriptor override val descriptor: ClassDescriptor get() = data().descriptor
override val annotated: Annotated get() = descriptor override val annotations: List<Annotation> get() = data().annotations
private val classId: ClassId get() = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass) private val classId: ClassId get() = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass)
@@ -40,7 +40,7 @@ internal class KFunctionImpl private constructor(
container, descriptor.name.asString(), RuntimeTypeMapper.mapSignature(descriptor).asString(), descriptor container, descriptor.name.asString(), RuntimeTypeMapper.mapSignature(descriptor).asString(), descriptor
) )
override val descriptor: FunctionDescriptor by ReflectProperties.lazySoft<FunctionDescriptor>(descriptorInitialValue) { override val descriptor: FunctionDescriptor by ReflectProperties.lazySoft(descriptorInitialValue) {
container.findFunctionDescriptor(name, signature) container.findFunctionDescriptor(name, signature)
} }
@@ -18,7 +18,6 @@ package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import kotlin.reflect.KParameter import kotlin.reflect.KParameter
import kotlin.reflect.KType import kotlin.reflect.KType
@@ -28,10 +27,10 @@ internal class KParameterImpl(
override val index: Int, override val index: Int,
override val kind: KParameter.Kind, override val kind: KParameter.Kind,
computeDescriptor: () -> ParameterDescriptor computeDescriptor: () -> ParameterDescriptor
) : KParameter, KAnnotatedElementImpl { ) : KParameter {
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor) private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
override val annotated: Annotated get() = descriptor override val annotations: List<Annotation> by ReflectProperties.lazySoft { descriptor.computeAnnotations() }
override val name: String? get() { override val name: String? get() {
val valueParameter = descriptor as? ValueParameterDescriptor ?: return null val valueParameter = descriptor as? ValueParameterDescriptor ?: return null
@@ -79,7 +79,7 @@ internal abstract class KPropertyImpl<out R> private constructor(
override abstract val getter: Getter<R> override abstract val getter: Getter<R>
private val descriptor_ = ReflectProperties.lazySoft<PropertyDescriptor>(descriptorInitialValue) { private val descriptor_ = ReflectProperties.lazySoft(descriptorInitialValue) {
container.findPropertyDescriptor(name, signature) container.findPropertyDescriptor(name, signature)
} }
@@ -42,8 +42,7 @@ internal class KTypeImpl(
) : KType { ) : KType {
internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType) internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType)
override val classifier: KClassifier? override val classifier: KClassifier? by ReflectProperties.lazySoft { convert(type) }
get() = convert(type)
private fun convert(type: KotlinType): KClassifier? { private fun convert(type: KotlinType): KClassifier? {
val descriptor = type.constructor.declarationDescriptor val descriptor = type.constructor.declarationDescriptor
@@ -71,14 +70,13 @@ internal class KTypeImpl(
} }
} }
override val arguments: List<KTypeProjection> override val arguments: List<KTypeProjection> by ReflectProperties.lazySoft arguments@ {
get() {
val typeArguments = type.arguments val typeArguments = type.arguments
if (typeArguments.isEmpty()) return emptyList() if (typeArguments.isEmpty()) return@arguments emptyList<KTypeProjection>()
val parameterizedTypeArguments by lazy(PUBLICATION) { javaType.parameterizedTypeArguments } val parameterizedTypeArguments by lazy(PUBLICATION) { javaType.parameterizedTypeArguments }
return typeArguments.mapIndexed { i, typeProjection -> typeArguments.mapIndexed { i, typeProjection ->
if (typeProjection.isStarProjection) { if (typeProjection.isStarProjection) {
KTypeProjection.STAR KTypeProjection.STAR
} }
@@ -26,12 +26,13 @@ internal class KTypeParameterImpl(override val descriptor: TypeParameterDescript
override val name: String override val name: String
get() = descriptor.name.asString() get() = descriptor.name.asString()
override val upperBounds: List<KType> override val upperBounds: List<KType> by ReflectProperties.lazySoft {
get() = descriptor.upperBounds.map { kotlinType -> descriptor.upperBounds.map { kotlinType ->
KTypeImpl(kotlinType) { KTypeImpl(kotlinType) {
TODO("Java type is not yet supported for type parameters: $descriptor") TODO("Java type is not yet supported for type parameters: $descriptor")
} }
} }
}
override val variance: KVariance override val variance: KVariance
get() = when (descriptor.variance) { get() = when (descriptor.variance) {
@@ -19,11 +19,14 @@ package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility 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.components.RuntimeSourceElementFactory
import org.jetbrains.kotlin.load.java.reflect.tryLoadClass 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.ReflectJavaClass
import org.jetbrains.kotlin.load.java.structure.reflect.safeClassLoader import org.jetbrains.kotlin.load.java.structure.reflect.safeClassLoader
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement 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.load.kotlin.reflect.ReflectKotlinClass
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
@@ -85,6 +88,16 @@ internal fun Visibility.toKVisibility(): KVisibility? =
else -> null else -> null
} }
internal fun Annotated.computeAnnotations(): List<Annotation> =
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 // TODO: wrap other exceptions
internal inline fun <R> reflectionCall(block: () -> R): R = internal inline fun <R> reflectionCall(block: () -> R): R =
try { try {