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:
+5
-2
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.serialization.deserialization.LocalClassResolverImpl
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
@@ -30,7 +31,8 @@ public class DeserializationComponentsForJava(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
classDataFinder: JavaClassDataFinder,
|
||||
annotationAndConstantLoader: BinaryClassAnnotationAndConstantLoaderImpl,
|
||||
packageFragmentProvider: LazyJavaPackageFragmentProvider
|
||||
packageFragmentProvider: LazyJavaPackageFragmentProvider,
|
||||
errorReporter: ErrorReporter
|
||||
) {
|
||||
val components: DeserializationComponents
|
||||
|
||||
@@ -38,7 +40,8 @@ public class DeserializationComponentsForJava(
|
||||
val localClassResolver = LocalClassResolverImpl()
|
||||
components = DeserializationComponents(
|
||||
storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider,
|
||||
localClassResolver, JavaFlexibleTypeCapabilitiesDeserializer, ClassDescriptorFactory.EMPTY, JavaTypeCapabilitiesLoader
|
||||
localClassResolver, errorReporter, JavaFlexibleTypeCapabilitiesDeserializer, ClassDescriptorFactory.EMPTY,
|
||||
JavaTypeCapabilitiesLoader
|
||||
)
|
||||
localClassResolver.setDeserializationComponents(components)
|
||||
}
|
||||
|
||||
+4
-1
@@ -64,7 +64,10 @@ public class RuntimeModuleData private constructor(public val deserialization: D
|
||||
val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, module)
|
||||
val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver)
|
||||
val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl(module, storageManager, reflectKotlinClassFinder, RuntimeErrorReporter)
|
||||
val deserializationComponentsForJava = DeserializationComponentsForJava(storageManager, module, javaClassDataFinder, binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider)
|
||||
val deserializationComponentsForJava = DeserializationComponentsForJava(
|
||||
storageManager, module, javaClassDataFinder, binaryClassAnnotationAndConstantLoader,
|
||||
lazyJavaPackageFragmentProvider, RuntimeErrorReporter
|
||||
)
|
||||
singleModuleClassResolver.resolver = javaDescriptorResolver
|
||||
deserializedDescriptorResolver.setComponents(deserializationComponentsForJava)
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ public fun createBuiltInPackageFragmentProvider(
|
||||
BuiltInsAnnotationAndConstantLoader(module),
|
||||
provider,
|
||||
localClassResolver,
|
||||
ErrorReporter.DO_NOTHING,
|
||||
FlexibleTypeCapabilitiesDeserializer.ThrowException,
|
||||
classDescriptorFactory
|
||||
)
|
||||
|
||||
+7
-2
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
+20
@@ -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
|
||||
|
||||
+25
-16
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user