Add BinaryVersion to DeserializationContext

This will be useful to implement version-dependent deserialization,
which is needed for gradual fixes of issues in metadata

 #KT-25120 In Progress
This commit is contained in:
Alexander Udalov
2018-07-11 19:14:21 +02:00
parent 1e9694f1db
commit 4122021090
40 changed files with 201 additions and 93 deletions
@@ -73,9 +73,10 @@ object JsAnalyzerFacade : ResolverForModuleFactory() {
.flatMap { KotlinJavascriptMetadataUtils.loadMetadata(it) }
.filter { it.version.isCompatible() }
.map { metadata ->
val (header, packageFragmentProtos) = KotlinJavascriptSerializationUtil.readModuleAsProto(metadata.body)
val (header, packageFragmentProtos) =
KotlinJavascriptSerializationUtil.readModuleAsProto(metadata.body, metadata.version)
createKotlinJavascriptPackageFragmentProvider(
moduleContext.storageManager, moduleDescriptor, header, packageFragmentProtos,
moduleContext.storageManager, moduleDescriptor, header, packageFragmentProtos, metadata.version,
container.get(), LookupTracker.DO_NOTHING
)
}
@@ -44,9 +44,10 @@ class KotlinBuiltInDecompiler : KotlinMetadataDecompiler<BuiltInsBinaryVersion>(
class BuiltInDefinitionFile(
proto: ProtoBuf.PackageFragment,
version: BuiltInsBinaryVersion,
val packageDirectory: VirtualFile,
val isMetadata: Boolean
) : FileWithMetadata.Compatible(proto, BuiltInSerializerProtocol) {
) : FileWithMetadata.Compatible(proto, version, BuiltInSerializerProtocol) {
override val classesToDecompile: List<ProtoBuf.Class>
get() = super.classesToDecompile.let { classes ->
if (isMetadata || !FILTER_OUT_CLASSES_EXISTING_AS_JVM_CLASS_FILES) classes
@@ -73,7 +74,8 @@ class BuiltInDefinitionFile(
}
val proto = ProtoBuf.PackageFragment.parseFrom(stream, BuiltInSerializerProtocol.extensionRegistry)
val result = BuiltInDefinitionFile(proto, file.parent, file.extension == MetadataPackageFragment.METADATA_FILE_EXTENSION)
val result =
BuiltInDefinitionFile(proto, version, file.parent, file.extension == MetadataPackageFragment.METADATA_FILE_EXTENSION)
val packageProto = result.proto.`package`
if (result.classesToDecompile.isEmpty() &&
packageProto.typeAliasCount == 0 && packageProto.functionCount == 0 && packageProto.propertyCount == 0) {
@@ -87,8 +87,9 @@ class DeserializerForClassfileDecompiler(
}
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(annotationData, strings)
val membersScope = DeserializedPackageMemberScope(
createDummyPackageFragment(header.packageName?.let(::FqName) ?: facadeFqName.parent()), packageProto, nameResolver,
JvmPackagePartSource(binaryClassForPackageClass, packageProto, nameResolver), deserializationComponents
createDummyPackageFragment(header.packageName?.let(::FqName) ?: facadeFqName.parent()),
packageProto, nameResolver, header.metadataVersion,
JvmPackagePartSource(binaryClassForPackageClass, packageProto, nameResolver), deserializationComponents
) { emptyList() }
return membersScope.getContributedDescriptors().toList()
}
@@ -145,6 +146,6 @@ class DirectoryBasedDataFinder(
}
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(data, strings)
return ClassData(nameResolver, classProto, KotlinJvmBinarySourceElement(binaryClass))
return ClassData(nameResolver, classProto, classHeader.metadataVersion, KotlinJvmBinarySourceElement(binaryClass))
}
}
@@ -101,7 +101,7 @@ abstract class KotlinMetadataDecompiler<out V : BinaryVersion>(
is FileWithMetadata.Compatible -> {
val packageFqName = file.packageFqName
val resolver = KotlinMetadataDeserializerForDecompiler(
packageFqName, file.proto, file.nameResolver,
packageFqName, file.proto, file.nameResolver, file.version,
targetPlatform, serializerProtocol, flexibleTypeDeserializer
)
val declarations = arrayListOf<DeclarationDescriptor>()
@@ -120,8 +120,9 @@ sealed class FileWithMetadata {
class Incompatible(val version: BinaryVersion) : FileWithMetadata()
open class Compatible(
val proto: ProtoBuf.PackageFragment,
serializerProtocol: SerializerExtensionProtocol
val proto: ProtoBuf.PackageFragment,
val version: BinaryVersion,
serializerProtocol: SerializerExtensionProtocol
) : FileWithMetadata() {
val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames)
val packageFqName = FqName(nameResolver.getPackageFqName(proto.`package`.getExtension(serializerProtocol.packageFqName)))
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolveEverythingToKotlinAnyLocalClassifierResolver
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.TargetPlatform
@@ -37,6 +38,7 @@ class KotlinMetadataDeserializerForDecompiler(
packageFqName: FqName,
private val proto: ProtoBuf.PackageFragment,
private val nameResolver: NameResolver,
private val metadataVersion: BinaryVersion,
override val targetPlatform: TargetPlatform,
serializerProtocol: SerializerExtensionProtocol,
flexibleTypeDeserializer: FlexibleTypeDeserializer
@@ -49,7 +51,8 @@ class KotlinMetadataDeserializerForDecompiler(
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
deserializationComponents = DeserializationComponents(
storageManager, moduleDescriptor, DeserializationConfiguration.Default, ProtoBasedClassDataFinder(proto, nameResolver),
storageManager, moduleDescriptor, DeserializationConfiguration.Default,
ProtoBasedClassDataFinder(proto, nameResolver, metadataVersion),
AnnotationAndConstantLoaderImpl(moduleDescriptor, notFoundClasses, serializerProtocol), packageFragmentProvider,
ResolveEverythingToKotlinAnyLocalClassifierResolver(builtIns), LoggingErrorReporter(LOG),
LookupTracker.DO_NOTHING, flexibleTypeDeserializer, emptyList(), notFoundClasses,
@@ -64,8 +67,8 @@ class KotlinMetadataDeserializerForDecompiler(
}
val membersScope = DeserializedPackageMemberScope(
createDummyPackageFragment(facadeFqName), proto.`package`, nameResolver, containerSource = null,
components = deserializationComponents
createDummyPackageFragment(facadeFqName), proto.`package`, nameResolver, metadataVersion, containerSource = null,
components = deserializationComponents
) { emptyList() }
return membersScope.getContributedDescriptors().toList()
@@ -51,7 +51,7 @@ open class KotlinMetadataStubBuilder(
val packageFqName = file.packageFqName
val nameResolver = file.nameResolver
val components = ClsStubBuilderComponents(
ProtoBasedClassDataFinder(file.proto, nameResolver),
ProtoBasedClassDataFinder(file.proto, nameResolver, file.version),
AnnotationLoaderForStubBuilderImpl(serializerProtocol),
virtualFile
)
@@ -43,6 +43,6 @@ class KotlinJavaScriptMetaFileDecompiler : KotlinMetadataDecompiler<JsMetadataVe
JsProtoBuf.Header.parseDelimitedFrom(stream)
val proto = ProtoBuf.PackageFragment.parseFrom(stream, JsSerializerProtocol.extensionRegistry)
return FileWithMetadata.Compatible(proto, JsSerializerProtocol)
return FileWithMetadata.Compatible(proto, version, JsSerializerProtocol)
}
}
@@ -247,7 +247,7 @@ private class ClassClsStubBuilder(
}
private fun createNestedClassStub(classBody: StubElement<out PsiElement>, nestedClassId: ClassId) {
val (nameResolver, classProto, sourceElement) =
val (nameResolver, classProto, _, sourceElement) =
c.components.classDataFinder.findClassData(nestedClassId)
?: c.components.virtualFileForDebug.let { rootFile ->
LOG.error(