Provide equals, hashCode, toString for classes in reflection model

This commit is contained in:
Alexander Udalov
2015-02-26 11:53:49 +03:00
parent a14b301f31
commit f36ef6f546
12 changed files with 80 additions and 40 deletions
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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<JavaClassifierType> = 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<JavaType> {
if (classifierType is ParameterizedType) {
return classifierType.getActualTypeArguments()!!.map { ReflectJavaType.create(it) }
}
return listOf()
return (type as? ParameterizedType)?.getActualTypeArguments()?.map { ReflectJavaType.create(it) } ?: listOf()
}
}
@@ -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
}
@@ -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
}
@@ -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()
}
@@ -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
}
@@ -29,7 +29,7 @@ public class ReflectJavaTypeParameter(
) : ReflectJavaElement(), JavaTypeParameter {
override fun getUpperBounds(): List<ReflectJavaClassifierType> {
val bounds = typeVariable.getBounds().map { bound -> ReflectJavaClassifierType(bound) }
if (bounds.singleOrNull()?.classifierType == javaClass<Any>()) return emptyList()
if (bounds.singleOrNull()?.type == javaClass<Any>()) 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
}
@@ -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
}
@@ -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<Any>()
override fun isExtends() = type.getUpperBounds().firstOrNull() != javaClass<Any>()
override fun getTypeProvider() = ReflectJavaTypeProvider
}
}
@@ -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 {