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
@@ -22,11 +22,15 @@ import java.io.File
interface IncrementalDataProvider {
/** gets header metadata (serialized [JsProtoBuf.Header]) from previous compilation */
val headerMetadata: ByteArray
/** gets non-dirty package parts data from previous compilation */
val compiledPackageParts: Map<File, TranslationResultValue>
val metadataVersion: IntArray
}
class IncrementalDataProviderImpl(
override val headerMetadata: ByteArray,
override val compiledPackageParts: Map<File, TranslationResultValue>
) : IncrementalDataProvider
override val compiledPackageParts: Map<File, TranslationResultValue>,
override val metadataVersion: IntArray
) : IncrementalDataProvider
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProvid
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.serialization.js.PackagesWithHeaderMetadata
import org.jetbrains.kotlin.utils.JsMetadataVersion
object TopDownAnalyzerFacadeForJS {
@JvmStatic
@@ -85,8 +86,12 @@ object TopDownAnalyzerFacadeForJS {
val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING
val expectActualTracker = configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER) ?: ExpectActualTracker.DoNothing
val languageVersionSettings = configuration.languageVersionSettings
val packageFragment = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER]?.let {
val metadata = PackagesWithHeaderMetadata(it.headerMetadata, it.compiledPackageParts.values.map { it.metadata })
val packageFragment = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER]?.let { incrementalData ->
val metadata = PackagesWithHeaderMetadata(
incrementalData.headerMetadata,
incrementalData.compiledPackageParts.values.map { it.metadata },
JsMetadataVersion(*incrementalData.metadataVersion)
)
KotlinJavascriptSerializationUtil.readDescriptors(
metadata, moduleContext.storageManager, moduleContext.module,
CompilerDeserializationConfiguration(languageVersionSettings), lookupTracker
@@ -250,8 +250,9 @@ public class JsConfig {
Name.special("<" + cached.getName() + ">"), storageManager, JsPlatform.INSTANCE.getBuiltIns()
);
KotlinJavaScriptLibraryParts parts = cached.getData();
PackageFragmentProvider provider = KotlinJavascriptPackageFragmentProviderKt.createKotlinJavascriptPackageFragmentProvider(
storageManager, moduleDescriptor, cached.getData().getHeader(), cached.getData().getBody(),
storageManager, moduleDescriptor, parts.getHeader(), parts.getBody(), parts.getMetadataVersion(),
new CompilerDeserializationConfiguration(languageVersionSettings),
LookupTracker.DO_NOTHING.INSTANCE
);
@@ -309,9 +310,9 @@ public class JsConfig {
);
LookupTracker lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER, LookupTracker.DO_NOTHING.INSTANCE);
KotlinJavaScriptLibraryParts parts = KotlinJavascriptSerializationUtil.readModuleAsProto(m.getBody());
KotlinJavaScriptLibraryParts parts = KotlinJavascriptSerializationUtil.readModuleAsProto(m.getBody(), m.getVersion());
PackageFragmentProvider provider = KotlinJavascriptPackageFragmentProviderKt.createKotlinJavascriptPackageFragmentProvider(
storageManager, moduleDescriptor, parts.getHeader(), parts.getBody(),
storageManager, moduleDescriptor, parts.getHeader(), parts.getBody(), m.getVersion(),
new CompilerDeserializationConfiguration(languageVersionSettings),
lookupTracker
);
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.utils.JsMetadataVersion
class KotlinJavascriptPackageFragment(
fqName: FqName,
@@ -38,8 +39,11 @@ class KotlinJavascriptPackageFragment(
module: ModuleDescriptor,
proto: ProtoBuf.PackageFragment,
header: JsProtoBuf.Header,
metadataVersion: JsMetadataVersion,
configuration: DeserializationConfiguration
) : DeserializedPackageFragmentImpl(fqName, storageManager, module, proto, JsContainerSource(fqName, header, configuration)) {
) : DeserializedPackageFragmentImpl(
fqName, storageManager, module, proto, metadataVersion, JsContainerSource(fqName, header, configuration)
) {
val fileMap: Map<Int, FileHolder> =
proto.getExtension(JsProtoBuf.packageFragmentFiles).fileList.withIndex().associate { (index, file) ->
(if (file.hasId()) file.id else index) to FileHolder(file.annotationList)
@@ -62,7 +62,9 @@ object KotlinJavascriptSerializationUtil {
ProtoBuf.PackageFragment.parseFrom(it, JsSerializerProtocol.extensionRegistry)
}
val headerProto = JsProtoBuf.Header.parseFrom(CodedInputStream.newInstance(metadata.header), JsSerializerProtocol.extensionRegistry)
return createKotlinJavascriptPackageFragmentProvider(storageManager, module, headerProto, scopeProto, configuration, lookupTracker)
return createKotlinJavascriptPackageFragmentProvider(
storageManager, module, headerProto, scopeProto, metadata.metadataVersion, configuration, lookupTracker
)
}
fun serializeMetadata(
@@ -302,7 +304,7 @@ object KotlinJavascriptSerializationUtil {
}
@JvmStatic
fun readModuleAsProto(metadata: ByteArray): KotlinJavaScriptLibraryParts {
fun readModuleAsProto(metadata: ByteArray, metadataVersion: JsMetadataVersion): KotlinJavaScriptLibraryParts {
val (header, content) = GZIPInputStream(ByteArrayInputStream(metadata)).use { stream ->
JsProtoBuf.Header.parseDelimitedFrom(stream, JsSerializerProtocol.extensionRegistry) to
JsProtoBuf.Library.parseFrom(stream, JsSerializerProtocol.extensionRegistry)
@@ -315,7 +317,7 @@ object KotlinJavascriptSerializationUtil {
JsProtoBuf.Library.Kind.UMD -> ModuleKind.UMD
}
return KotlinJavaScriptLibraryParts(header, content.packageFragmentList, moduleKind, content.importedModuleList)
return KotlinJavaScriptLibraryParts(header, content.packageFragmentList, moduleKind, content.importedModuleList, metadataVersion)
}
}
@@ -323,7 +325,8 @@ data class KotlinJavaScriptLibraryParts(
val header: JsProtoBuf.Header,
val body: List<ProtoBuf.PackageFragment>,
val kind: ModuleKind,
val importedModules: List<String>
val importedModules: List<String>,
val metadataVersion: JsMetadataVersion
)
internal fun DeclarationDescriptor.extractFileId(): Int? = when (this) {
@@ -16,4 +16,10 @@
package org.jetbrains.kotlin.serialization.js
class PackagesWithHeaderMetadata(val header: ByteArray, val packages: List<ByteArray>)
import org.jetbrains.kotlin.utils.JsMetadataVersion
class PackagesWithHeaderMetadata(
val header: ByteArray,
val packages: List<ByteArray>,
val metadataVersion: JsMetadataVersion
)
@@ -28,18 +28,20 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.JsMetadataVersion
fun createKotlinJavascriptPackageFragmentProvider(
storageManager: StorageManager,
module: ModuleDescriptor,
header: JsProtoBuf.Header,
packageFragmentProtos: List<ProtoBuf.PackageFragment>,
metadataVersion: JsMetadataVersion,
configuration: DeserializationConfiguration,
lookupTracker: LookupTracker
): PackageFragmentProvider {
val packageFragments: MutableList<PackageFragmentDescriptor> = packageFragmentProtos.mapNotNullTo(mutableListOf()) { proto ->
proto.fqName?.let { fqName ->
KotlinJavascriptPackageFragment(fqName, storageManager, module, proto, header, configuration)
KotlinJavascriptPackageFragment(fqName, storageManager, module, proto, header, metadataVersion, configuration)
}
}
@@ -59,6 +59,7 @@ import org.jetbrains.kotlin.test.KotlinTestUtils.TestFileFactory
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.JsMetadataVersion
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
import java.io.*
@@ -409,10 +410,11 @@ abstract class BasicBoxTest(
return String(out.toByteArray(), Charset.forName("UTF-8"))
}
private fun metadataAsString(metadata: String): String {
val containers = mutableListOf<KotlinJavascriptMetadata>()
KotlinJavascriptMetadataUtils.parseMetadata(metadata, containers)
val metadataParts = KotlinJavascriptSerializationUtil.readModuleAsProto(containers.single().body).body
private fun metadataAsString(metadataText: String): String {
val metadata = mutableListOf<KotlinJavascriptMetadata>().apply {
KotlinJavascriptMetadataUtils.parseMetadata(metadataText, this)
}.single()
val metadataParts = KotlinJavascriptSerializationUtil.readModuleAsProto(metadata.body, metadata.version).body
return metadataParts.joinToString("-----\n") {
val binary = it.toByteArray()
DebugProtoBuf.PackageFragment.parseFrom(binary, JsSerializerProtocol.extensionRegistry).toString()
@@ -576,8 +578,10 @@ abstract class BasicBoxTest(
if (hasFilesToRecompile) {
val header = incrementalData?.header
if (header != null) {
configuration.put(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER,
IncrementalDataProviderImpl(header, incrementalData.translatedFiles))
configuration.put(
JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER,
IncrementalDataProviderImpl(header, incrementalData.translatedFiles, JsMetadataVersion.INSTANCE.toArray())
)
}
configuration.put(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER, IncrementalResultsConsumerImpl())
@@ -743,7 +747,7 @@ abstract class BasicBoxTest(
companion object {
val METADATA_CACHE = (JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).flatMap { path ->
KotlinJavascriptMetadataUtils.loadMetadata(path).map { metadata ->
val parts = KotlinJavascriptSerializationUtil.readModuleAsProto(metadata.body)
val parts = KotlinJavascriptSerializationUtil.readModuleAsProto(metadata.body, metadata.version)
JsModuleDescriptor(metadata.moduleName, parts.kind, parts.importedModules, parts)
}
}