Extract common logic into AbstractTypeConstructor

Mostly it's about detecting loops in supertypes

Test data changes:
- Loops are being disconnected in Java classes too
- functions.kt: loops disconnection mechanism runs supertypes calculation,
so when we start check T it forces F' supertypes calculation, that ends
with CYCLIC_GENERIC_UPPER_BOUND reported on F

 #KT-11287 In Progress
This commit is contained in:
Denis Zharkov
2016-03-07 16:11:41 +03:00
parent ea9f1b5649
commit b8b48c5f98
21 changed files with 308 additions and 366 deletions
@@ -128,16 +128,15 @@ class LazyJavaClassDescriptor(
override fun toString() = "lazy java class $fqName"
private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor() {
private inner class LazyJavaClassTypeConstructor : AbstractClassTypeConstructor(c.storageManager) {
private val parameters = c.storageManager.createLazyValue {
this@LazyJavaClassDescriptor.computeConstructorTypeParameters()
}
override fun getParameters(): List<TypeParameterDescriptor> = parameters()
private val supertypes = c.storageManager.createLazyValue<Collection<KotlinType>> {
val javaTypes = jClass.getSupertypes()
override fun computeSupertypes(): Collection<KotlinType> {
val javaTypes = jClass.supertypes
val result = ArrayList<KotlinType>(javaTypes.size)
val incomplete = ArrayList<JavaType>(0)
@@ -145,12 +144,12 @@ class LazyJavaClassDescriptor(
for (javaType in javaTypes) {
val jetType = c.typeResolver.transformJavaType(javaType, TypeUsage.SUPERTYPE.toAttributes())
if (jetType.isError()) {
if (jetType.isError) {
incomplete.add(javaType)
continue
}
if (jetType.getConstructor() == purelyImplementedSupertype?.getConstructor()) {
if (jetType.constructor == purelyImplementedSupertype?.constructor) {
continue
}
@@ -162,12 +161,12 @@ class LazyJavaClassDescriptor(
result.addIfNotNull(purelyImplementedSupertype)
if (incomplete.isNotEmpty()) {
c.components.errorReporter.reportIncompleteHierarchy(getDeclarationDescriptor(), incomplete.map { javaType ->
(javaType as JavaClassifierType).getPresentableText()
c.components.errorReporter.reportIncompleteHierarchy(declarationDescriptor, incomplete.map { javaType ->
(javaType as JavaClassifierType).presentableText
})
}
if (result.isNotEmpty()) result.toReadOnlyList() else listOf(c.module.builtIns.getAnyType())
return if (result.isNotEmpty()) result.toReadOnlyList() else listOf(c.module.builtIns.anyType)
}
private fun getPurelyImplementedSupertype(): KotlinType? {
@@ -179,10 +178,10 @@ class LazyJavaClassDescriptor(
val classDescriptor = c.module.builtIns.getBuiltInClassByFqNameNullable(purelyImplementedFqName) ?: return null
if (classDescriptor.getTypeConstructor().getParameters().size != getParameters().size) return null
if (classDescriptor.typeConstructor.parameters.size != getTypeConstructor().parameters.size) return null
val parametersAsTypeProjections = getParameters().map {
parameter -> TypeProjectionImpl(Variance.INVARIANT, parameter.getDefaultType())
val parametersAsTypeProjections = getTypeConstructor().parameters.map {
parameter -> TypeProjectionImpl(Variance.INVARIANT, parameter.defaultType)
}
return KotlinTypeImpl.create(
@@ -192,17 +191,18 @@ class LazyJavaClassDescriptor(
}
private fun getPurelyImplementsFqNameFromAnnotation(): FqName? {
val annotation = this@LazyJavaClassDescriptor.
getAnnotations().
findAnnotation(JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION) ?: return null
val annotation =
this@LazyJavaClassDescriptor.getAnnotations().findAnnotation(JvmAnnotationNames.PURELY_IMPLEMENTS_ANNOTATION)
?: return null
val fqNameString = (annotation.getAllValueArguments().values.singleOrNull() as? StringValue)?.value ?: return null
val fqNameString = (annotation.allValueArguments.values.singleOrNull() as? StringValue)?.value ?: return null
if (!isValidJavaFqName(fqNameString)) return null
return FqName(fqNameString)
}
override fun getSupertypes(): Collection<KotlinType> = supertypes()
override val supertypeLoopChecker: SupertypeLoopChecker
get() = c.components.supertypeLoopChecker
override fun getAnnotations() = Annotations.EMPTY
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
@@ -39,7 +40,7 @@ class LazyJavaTypeParameterDescriptor(
Variance.INVARIANT,
/* isReified = */ false,
index,
SourceElement.NO_SOURCE
SourceElement.NO_SOURCE, c.components.supertypeLoopChecker
) {
override fun resolveUpperBounds(): List<KotlinType> {
@@ -55,9 +56,7 @@ class LazyJavaTypeParameterDescriptor(
}
}
override fun getSupertypeLoopChecker() = c.components.supertypeLoopChecker
override fun reportCycleError(type: KotlinType) {
override fun reportSupertypeLoopError(type: KotlinType) {
// Do nothing
}
}