Report incomplete hierarchy error for deserialized types

#KT-5129 Fixed

Delete a JPS test that was specifically testing that we would not fail in this
situation; now there's a compilation error
This commit is contained in:
Alexander Udalov
2015-02-09 17:52:42 +03:00
parent b1d9e5c961
commit 949144e0c0
15 changed files with 118 additions and 82 deletions
@@ -57,7 +57,12 @@ class DeserializedType(
override fun getCapabilities() = c.components.typeCapabilitiesLoader.loadCapabilities(typeProto)
private fun <E: Any> List<E>.getOrNull(index: Int): E? {
return if (index in indices) this[index] else null
fun getPresentableText(): String {
val typeConstructorData = typeProto.getTypeConstructorData()
val id = typeConstructorData.id
return if (typeConstructorData.kind == TypeConstructorKind.CLASS)
c.nameResolver.getClassId(id).asSingleFqName().asString()
else
"Unknown type parameter $id"
}
}
@@ -32,4 +32,24 @@ public interface ErrorReporter {
void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor);
void reportLoadingError(@NotNull String message, @Nullable Exception exception);
ErrorReporter DO_NOTHING = new ErrorReporter() {
@Override
public void reportIncompatibleAbiVersion(
@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion
) {
}
@Override
public void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses) {
}
@Override
public void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
}
@Override
public void reportLoadingError(@NotNull String message, @Nullable Exception exception) {
}
};
}
@@ -31,6 +31,7 @@ public class DeserializationComponents(
public val annotationAndConstantLoader: AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>, AnnotationWithTarget>,
public val packageFragmentProvider: PackageFragmentProvider,
public val localClassResolver: LocalClassResolver,
public val errorReporter: ErrorReporter,
public val flexibleTypeCapabilitiesDeserializer: FlexibleTypeCapabilitiesDeserializer,
public val fictitiousClassDescriptorFactory: ClassDescriptorFactory,
public val typeCapabilitiesLoader: TypeCapabilitiesLoader = TypeCapabilitiesLoader.NONE
@@ -32,11 +32,14 @@ import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
import org.jetbrains.kotlin.serialization.deserialization.DeserializedType
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.upperIfFlexible
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import org.jetbrains.kotlin.utils.toReadOnlyList
import java.util.*
public class DeserializedClassDescriptor(
@@ -132,12 +135,25 @@ public class DeserializedClassDescriptor(
override fun getCompanionObjectDescriptor(): ClassDescriptor? = companionObjectDescriptor()
private fun computeSuperTypes(): Collection<JetType> {
val supertypes = ArrayList<JetType>(classProto.getSupertypeCount())
for (supertype in classProto.getSupertypeList()) {
supertypes.add(c.typeDeserializer.type(supertype))
private fun computeSupertypes(): Collection<JetType> {
val result = ArrayList<JetType>(classProto.supertypeCount)
val unresolved = ArrayList<DeserializedType>(0)
for (supertypeProto in classProto.supertypeList) {
val supertype = c.typeDeserializer.type(supertypeProto)
if (supertype.isError) {
unresolved.add(supertype.upperIfFlexible() as? DeserializedType ?: error("Not a deserialized type: $supertype"))
}
else {
result.add(supertype)
}
}
return supertypes
if (unresolved.isNotEmpty()) {
c.components.errorReporter.reportIncompleteHierarchy(this, unresolved.map(DeserializedType::getPresentableText))
}
return result.toReadOnlyList()
}
internal fun hasNestedClass(name: Name): Boolean {
@@ -149,20 +165,13 @@ public class DeserializedClassDescriptor(
override fun getSource() = sourceElement
private inner class DeserializedClassTypeConstructor : AbstractClassTypeConstructor() {
private val supertypes = computeSuperTypes()
private val supertypes = c.storageManager.createLazyValue {
computeSupertypes()
}
override fun getParameters() = c.typeDeserializer.ownTypeParameters
override fun getSupertypes(): Collection<JetType> {
// We cannot have error supertypes because subclasses inherit error functions from them
// Filtering right away means copying the list every time, so we check for the rare condition first, and only then filter
for (supertype in supertypes) {
if (supertype.isError()) {
return supertypes.filter { !it.isError() }
}
}
return supertypes
}
override fun getSupertypes() = supertypes()
override fun isFinal() = !getModality().isOverridable()