From a5a60b69176c3f85e68a336685e1e10d75a39db9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 18 Mar 2015 18:28:36 +0300 Subject: [PATCH] Move code from file named util.kt to meaningful place --- .../jvm/internal/KCallableContainerImpl.kt | 103 +++++++++++++++ .../src/kotlin/reflect/jvm/internal/util.kt | 123 ------------------ 2 files changed, 103 insertions(+), 123 deletions(-) delete mode 100644 core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableContainerImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableContainerImpl.kt index ec512ff6357..c35c62f08f6 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableContainerImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableContainerImpl.kt @@ -17,9 +17,19 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.load.java.structure.reflect.classId +import org.jetbrains.kotlin.load.java.structure.reflect.classLoader +import org.jetbrains.kotlin.load.java.structure.reflect.createArrayType import org.jetbrains.kotlin.load.java.structure.reflect.desc +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.JetScope +import org.jetbrains.kotlin.serialization.ProtoBuf +import org.jetbrains.kotlin.serialization.deserialization.NameResolver +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.JvmType.PrimitiveType.* +import java.lang.reflect.Field +import java.lang.reflect.Method import kotlin.reflect.KotlinReflectionInternalError abstract class KCallableContainerImpl { @@ -51,4 +61,97 @@ abstract class KCallableContainerImpl { properties.single() as PropertyDescriptor } + + // TODO: check resulting method's return type + fun findMethodBySignature(signature: JvmProtoBuf.JvmMethodSignature, nameResolver: NameResolver): Method? { + val name = nameResolver.getString(signature.getName()) + val classLoader = jClass.classLoader + val parameterTypes = signature.getParameterTypeList().map { jvmType -> + loadJvmType(jvmType, nameResolver, classLoader) + }.copyToArray() + return try { + jClass.getMaybeDeclaredMethod(name, *parameterTypes) + } + catch (e: NoSuchMethodException) { + null + } + } + + // TODO: check resulting field's type + fun findFieldBySignature( + proto: ProtoBuf.Callable, + signature: JvmProtoBuf.JvmFieldSignature, + nameResolver: NameResolver + ): Field? { + val name = nameResolver.getString(signature.getName()) + + val owner = + when { + proto.hasExtension(JvmProtoBuf.implClassName) -> { + val implClassName = nameResolver.getName(proto.getExtension(JvmProtoBuf.implClassName)) + // TODO: store fq name of impl class name in jvm_descriptors.proto + val classId = ClassId(jClass.classId.getPackageFqName(), implClassName) + jClass.classLoader.loadClass(classId.asSingleFqName().asString()) + } + signature.getIsStaticInOuter() -> { + jClass.getEnclosingClass() ?: throw KotlinReflectionInternalError("Inconsistent metadata for field $name in $jClass") + } + else -> jClass + } + + return try { + owner.getDeclaredField(name) + } + catch (e: NoSuchFieldException) { + null + } + } + + private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes: Class<*>): Method { + try { + return getMethod(name, *parameterTypes) + } + catch (e: NoSuchMethodException) { + // This is needed to support private methods + return getDeclaredMethod(name, *parameterTypes) + } + } + + /* private // KT-5786 */ fun loadJvmType( + type: JvmProtoBuf.JvmType, + nameResolver: NameResolver, + classLoader: ClassLoader, + arrayDimension: Int = type.getArrayDimension() + ): Class<*> { + if (arrayDimension > 0) { + // TODO: test multi-dimensional arrays + return loadJvmType(type, nameResolver, classLoader, arrayDimension - 1).createArrayType() + } + + if (type.hasPrimitiveType()) { + return PRIMITIVE_TYPES[type.getPrimitiveType()] + ?: throw KotlinReflectionInternalError("Unknown primitive type: ${type.getPrimitiveType()}") + } + + if (type.hasClassFqName()) { + val fqName = nameResolver.getFqName(type.getClassFqName()) + return classLoader.loadClass(fqName.asString()) + } + + throw KotlinReflectionInternalError("Inconsistent metadata for JVM type") + } + + companion object { + private val PRIMITIVE_TYPES = mapOf( + VOID to Void.TYPE, + BOOLEAN to java.lang.Boolean.TYPE, + CHAR to java.lang.Character.TYPE, + BYTE to java.lang.Byte.TYPE, + SHORT to java.lang.Short.TYPE, + INT to java.lang.Integer.TYPE, + FLOAT to java.lang.Float.TYPE, + LONG to java.lang.Long.TYPE, + DOUBLE to java.lang.Double.TYPE + ) + } } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt deleted file mode 100644 index f84c2be43ec..00000000000 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt +++ /dev/null @@ -1,123 +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.load.java.structure.reflect.classId -import org.jetbrains.kotlin.load.java.structure.reflect.classLoader -import org.jetbrains.kotlin.load.java.structure.reflect.createArrayType -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.serialization.ProtoBuf -import org.jetbrains.kotlin.serialization.deserialization.NameResolver -import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf -import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.JvmType.PrimitiveType.* -import java.lang.reflect.Field -import java.lang.reflect.Method -import kotlin.reflect.KotlinReflectionInternalError - - -private fun Class<*>.getMaybeDeclaredMethod(name: String, vararg parameterTypes: Class<*>): Method { - try { - return getMethod(name, *parameterTypes) - } - catch (e: NoSuchMethodException) { - // This is needed to support private methods - return getDeclaredMethod(name, *parameterTypes) - } -} - - -// TODO: check resulting method's return type -private fun KCallableContainerImpl.findMethodBySignature(signature: JvmProtoBuf.JvmMethodSignature, nameResolver: NameResolver): Method? { - val name = nameResolver.getString(signature.getName()) - val classLoader = jClass.classLoader - val parameterTypes = signature.getParameterTypeList().map { jvmType -> - loadJvmType(jvmType, nameResolver, classLoader) - }.copyToArray() - return try { - jClass.getMaybeDeclaredMethod(name, *parameterTypes) - } - catch (e: NoSuchMethodException) { - null - } -} - -// TODO: check resulting field's type -private fun KCallableContainerImpl.findFieldBySignature( - proto: ProtoBuf.Callable, - signature: JvmProtoBuf.JvmFieldSignature, - nameResolver: NameResolver -): Field? { - val name = nameResolver.getString(signature.getName()) - - val owner = - when { - proto.hasExtension(JvmProtoBuf.implClassName) -> { - val implClassName = nameResolver.getName(proto.getExtension(JvmProtoBuf.implClassName)) - // TODO: store fq name of impl class name in jvm_descriptors.proto - val classId = ClassId(jClass.classId.getPackageFqName(), implClassName) - jClass.classLoader.loadClass(classId.asSingleFqName().asString()) - } - signature.getIsStaticInOuter() -> { - jClass.getEnclosingClass() ?: throw KotlinReflectionInternalError("Inconsistent metadata for field $name in $jClass") - } - else -> jClass - } - - return try { - owner.getDeclaredField(name) - } - catch (e: NoSuchFieldException) { - null - } -} - - -private val PRIMITIVE_TYPES = mapOf( - VOID to Void.TYPE, - BOOLEAN to java.lang.Boolean.TYPE, - CHAR to java.lang.Character.TYPE, - BYTE to java.lang.Byte.TYPE, - SHORT to java.lang.Short.TYPE, - INT to java.lang.Integer.TYPE, - FLOAT to java.lang.Float.TYPE, - LONG to java.lang.Long.TYPE, - DOUBLE to java.lang.Double.TYPE -) - -private fun loadJvmType( - type: JvmProtoBuf.JvmType, - nameResolver: NameResolver, - classLoader: ClassLoader, - arrayDimension: Int = type.getArrayDimension() -): Class<*> { - if (arrayDimension > 0) { - // TODO: test multi-dimensional arrays - return loadJvmType(type, nameResolver, classLoader, arrayDimension - 1).createArrayType() - } - - if (type.hasPrimitiveType()) { - return PRIMITIVE_TYPES[type.getPrimitiveType()] - ?: throw KotlinReflectionInternalError("Unknown primitive type: ${type.getPrimitiveType()}") - } - - if (type.hasClassFqName()) { - val fqName = nameResolver.getFqName(type.getClassFqName()) - return classLoader.loadClass(fqName.asString()) - } - - throw KotlinReflectionInternalError("Inconsistent metadata for JVM type") -}