From f36ef6f5464367aca4c3fe31d374b1a5d580003a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 26 Feb 2015 11:53:49 +0300 Subject: [PATCH] Provide equals, hashCode, toString for classes in reflection model --- .../reflect/ReflectJavaAnnotation.kt | 6 +++ .../structure/reflect/ReflectJavaArrayType.kt | 13 ++++++- .../structure/reflect/ReflectJavaClass.kt | 6 +++ .../reflect/ReflectJavaClassifierType.kt | 13 +++---- .../structure/reflect/ReflectJavaMember.kt | 6 +++ .../structure/reflect/ReflectJavaPackage.kt | 10 ++++- .../reflect/ReflectJavaPrimitiveType.kt | 4 +- .../java/structure/reflect/ReflectJavaType.kt | 37 +++++++++---------- .../reflect/ReflectJavaTypeParameter.kt | 5 ++- .../reflect/ReflectJavaValueParameter.kt | 2 + .../reflect/ReflectJavaWildcardType.kt | 12 +++--- .../load/kotlin/reflect/ReflectKotlinClass.kt | 6 +++ 12 files changed, 80 insertions(+), 40 deletions(-) diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt index 0f080cc3d66..527960027bb 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaAnnotation.kt @@ -37,4 +37,10 @@ public class ReflectJavaAnnotation(private val annotation: Annotation) : Reflect override fun resolve() = ReflectJavaClass(annotation.annotationType()) override fun getClassId() = annotation.annotationType().classId + + override fun equals(other: Any?) = other is ReflectJavaAnnotation && annotation == other.annotation + + override fun hashCode() = annotation.hashCode() + + override fun toString() = javaClass.getName() + ": " + annotation } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaArrayType.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaArrayType.kt index b950c361aa4..fb6f8621ec7 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaArrayType.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaArrayType.kt @@ -17,8 +17,17 @@ package org.jetbrains.kotlin.load.java.structure.reflect import org.jetbrains.kotlin.load.java.structure.JavaArrayType +import java.lang.reflect.GenericArrayType import java.lang.reflect.Type -public class ReflectJavaArrayType(private val componentType: Type) : ReflectJavaType(), JavaArrayType { - override fun getComponentType() = ReflectJavaType.create(componentType) +public class ReflectJavaArrayType(override val type: Type) : ReflectJavaType(), JavaArrayType { + private val componentType: ReflectJavaType = with (type) { + when { + this is GenericArrayType -> ReflectJavaType.create(getGenericComponentType()) + this is Class<*> && isArray() -> ReflectJavaType.create(getComponentType()) + else -> throw IllegalArgumentException("Not an array type (${type.javaClass}): $type") + } + } + + override fun getComponentType() = componentType } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt index 8944c7c6454..f1cbcc0f075 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClass.kt @@ -102,4 +102,10 @@ public class ReflectJavaClass(private val klass: Class<*>) : ReflectJavaElement( override fun isFinal() = Modifier.isFinal(klass.getModifiers()) override fun getVisibility() = calculateVisibility(klass.getModifiers()) + + override fun equals(other: Any?) = other is ReflectJavaClass && klass == other.klass + + override fun hashCode() = klass.hashCode() + + override fun toString() = javaClass.getName() + ": " + klass } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClassifierType.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClassifierType.kt index c8618d1e352..f18d036a06f 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClassifierType.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaClassifierType.kt @@ -24,9 +24,9 @@ import java.lang.reflect.ParameterizedType import java.lang.reflect.Type import java.lang.reflect.TypeVariable -public class ReflectJavaClassifierType(val classifierType: Type) : ReflectJavaType(), JavaClassifierType { +public class ReflectJavaClassifierType(public override val type: Type) : ReflectJavaType(), JavaClassifierType { private val classifier: JavaClassifier = run { - val type = classifierType + val type = type when (type) { is Class<*> -> ReflectJavaClass(type) is TypeVariable<*> -> ReflectJavaTypeParameter(type) @@ -41,14 +41,11 @@ public class ReflectJavaClassifierType(val classifierType: Type) : ReflectJavaTy override fun getSupertypes(): Collection = throw UnsupportedOperationException() - override fun getPresentableText(): String = classifierType.toString() + override fun getPresentableText(): String = type.toString() - override fun isRaw(): Boolean = with(classifierType) { this is Class<*> && getTypeParameters().isNotEmpty() } + override fun isRaw(): Boolean = with(type) { this is Class<*> && getTypeParameters().isNotEmpty() } override fun getTypeArguments(): List { - if (classifierType is ParameterizedType) { - return classifierType.getActualTypeArguments()!!.map { ReflectJavaType.create(it) } - } - return listOf() + return (type as? ParameterizedType)?.getActualTypeArguments()?.map { ReflectJavaType.create(it) } ?: listOf() } } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaMember.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaMember.kt index b8316aba2e9..1607d31abce 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaMember.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaMember.kt @@ -53,4 +53,10 @@ public abstract class ReflectJavaMember : ReflectJavaElement(), ReflectJavaAnnot } return result } + + override fun equals(other: Any?) = other is ReflectJavaMember && member == other.member + + override fun hashCode() = member.hashCode() + + override fun toString() = javaClass.getName() + ": " + member } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt index b44d6fdf393..050b05a90c9 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPackage.kt @@ -16,9 +16,9 @@ package org.jetbrains.kotlin.load.java.structure.reflect -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.load.java.structure.JavaPackage import org.jetbrains.kotlin.load.java.structure.JavaClass +import org.jetbrains.kotlin.load.java.structure.JavaPackage +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name public class ReflectJavaPackage(private val fqName: FqName) : ReflectJavaElement(), JavaPackage { @@ -33,4 +33,10 @@ public class ReflectJavaPackage(private val fqName: FqName) : ReflectJavaElement // A package at runtime can't know what sub packages it has and has not return listOf() } + + override fun equals(other: Any?) = other is ReflectJavaPackage && fqName == other.fqName + + override fun hashCode() = fqName.hashCode() + + override fun toString() = javaClass.getName() + ": " + fqName } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPrimitiveType.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPrimitiveType.kt index cd66e0c70f4..4dc3d33b86a 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPrimitiveType.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaPrimitiveType.kt @@ -18,6 +18,6 @@ package org.jetbrains.kotlin.load.java.structure.reflect import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType -public class ReflectJavaPrimitiveType(private val klass: Class<*>): ReflectJavaType(), JavaPrimitiveType { - override fun getCanonicalText() = klass.getName() +public class ReflectJavaPrimitiveType(override val type: Class<*>): ReflectJavaType(), JavaPrimitiveType { + override fun getCanonicalText() = type.getName() } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaType.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaType.kt index db0cf58d1c7..d133bc065c8 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaType.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaType.kt @@ -18,30 +18,29 @@ package org.jetbrains.kotlin.load.java.structure.reflect import org.jetbrains.kotlin.load.java.structure.JavaArrayType import org.jetbrains.kotlin.load.java.structure.JavaType -import java.lang.reflect.* - -private val PRIMITIVE_TYPES = setOf( - java.lang.Integer.TYPE, java.lang.Character.TYPE, java.lang.Byte.TYPE, java.lang.Long.TYPE, - java.lang.Short.TYPE, java.lang.Boolean.TYPE, java.lang.Double.TYPE, java.lang.Float.TYPE, - java.lang.Void.TYPE -) +import java.lang.reflect.GenericArrayType +import java.lang.reflect.Type +import java.lang.reflect.WildcardType public abstract class ReflectJavaType : JavaType { + protected abstract val type: Type + override fun createArrayType(): JavaArrayType = throw UnsupportedOperationException() - class object { - fun create(reflectType: Type): ReflectJavaType { - return when (reflectType) { - in PRIMITIVE_TYPES -> ReflectJavaPrimitiveType(reflectType as Class<*>) - is GenericArrayType -> ReflectJavaArrayType(reflectType.getGenericComponentType()!!) - is Class<*> -> { - if (reflectType.isArray()) ReflectJavaArrayType(reflectType.getComponentType()!!) - else ReflectJavaClassifierType(reflectType) - } - is TypeVariable<*>, is ParameterizedType -> ReflectJavaClassifierType(reflectType) - is WildcardType -> ReflectJavaWildcardType(reflectType) - else -> throw UnsupportedOperationException("Unsupported type (${reflectType.javaClass}): $reflectType") + default object Factory { + fun create(type: Type): ReflectJavaType { + return when { + type is Class<*> && type.isPrimitive() -> ReflectJavaPrimitiveType(type) + type is GenericArrayType, type is Class<*> && type.isArray() -> ReflectJavaArrayType(type) + type is WildcardType -> ReflectJavaWildcardType(type) + else -> ReflectJavaClassifierType(type) } } } + + override fun equals(other: Any?) = other is ReflectJavaType && type == other.type + + override fun hashCode() = type.hashCode() + + override fun toString() = javaClass.getName() + ": " + type } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaTypeParameter.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaTypeParameter.kt index 03a8b33bd6e..3e6d8bc366e 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaTypeParameter.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaTypeParameter.kt @@ -29,7 +29,7 @@ public class ReflectJavaTypeParameter( ) : ReflectJavaElement(), JavaTypeParameter { override fun getUpperBounds(): List { val bounds = typeVariable.getBounds().map { bound -> ReflectJavaClassifierType(bound) } - if (bounds.singleOrNull()?.classifierType == javaClass()) return emptyList() + if (bounds.singleOrNull()?.type == javaClass()) return emptyList() return bounds } @@ -53,5 +53,8 @@ public class ReflectJavaTypeParameter( override fun getName() = Name.identifier(typeVariable.getName()) override fun equals(other: Any?) = other is ReflectJavaTypeParameter && typeVariable == other.typeVariable + override fun hashCode() = typeVariable.hashCode() + + override fun toString() = javaClass.getName() + ": " + typeVariable } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaValueParameter.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaValueParameter.kt index 6cae4b3cb82..d5d9f2f555a 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaValueParameter.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaValueParameter.kt @@ -31,4 +31,6 @@ public class ReflectJavaValueParameter( override fun getName() = null // TODO: use ParameterNames on JDK 8 override fun getType() = returnType override fun isVararg() = isVararg + + override fun toString() = javaClass.getName() + ": " + (if (isVararg) "vararg " else "") + getName() + ": " + returnType } diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaWildcardType.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaWildcardType.kt index 178a12f2a94..8c535d8d45a 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaWildcardType.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/java/structure/reflect/ReflectJavaWildcardType.kt @@ -19,12 +19,12 @@ package org.jetbrains.kotlin.load.java.structure.reflect import org.jetbrains.kotlin.load.java.structure.JavaWildcardType import java.lang.reflect.WildcardType -public class ReflectJavaWildcardType(private val wildcardType: WildcardType): ReflectJavaType(), JavaWildcardType { +public class ReflectJavaWildcardType(override val type: WildcardType): ReflectJavaType(), JavaWildcardType { override fun getBound(): ReflectJavaType? { - val upperBounds = wildcardType.getUpperBounds() - val lowerBounds = wildcardType.getLowerBounds() + val upperBounds = type.getUpperBounds() + val lowerBounds = type.getLowerBounds() if (upperBounds.size() > 1 || lowerBounds.size() > 1) { - throw UnsupportedOperationException("Wildcard types with many bounds are not yet supported: $wildcardType") + throw UnsupportedOperationException("Wildcard types with many bounds are not yet supported: $type") } return when { lowerBounds.size() == 1 -> ReflectJavaType.create(lowerBounds.single()) @@ -33,7 +33,7 @@ public class ReflectJavaWildcardType(private val wildcardType: WildcardType): Re } } - override fun isExtends() = wildcardType.getUpperBounds().firstOrNull() != javaClass() + override fun isExtends() = type.getUpperBounds().firstOrNull() != javaClass() override fun getTypeProvider() = ReflectJavaTypeProvider -} \ No newline at end of file +} diff --git a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/ReflectKotlinClass.kt b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/ReflectKotlinClass.kt index c927cba1528..b441cc556a8 100644 --- a/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/ReflectKotlinClass.kt +++ b/core/descriptors.runtime/src/org/jetbrains/kotlin/load/kotlin/reflect/ReflectKotlinClass.kt @@ -60,6 +60,12 @@ public class ReflectKotlinClass private( override fun visitMembers(visitor: KotlinJvmBinaryClass.MemberVisitor) { ReflectClassStructure.visitMembers(klass, visitor) } + + override fun equals(other: Any?) = other is ReflectKotlinClass && klass == other.klass + + override fun hashCode() = klass.hashCode() + + override fun toString() = javaClass.getName() + ": " + klass } private object ReflectClassStructure {