Drop JvmMetadataVersion.skipCheck, support this correctly

Pass the value of this flag via DeserializationConfiguration
This commit is contained in:
Alexander Udalov
2017-02-08 18:31:02 +03:00
parent e1463f9e0f
commit a1a71a01b1
18 changed files with 73 additions and 70 deletions
@@ -40,7 +40,7 @@ private fun Iterable<PackageParts>.addCompiledParts(state: GenerationState): Lis
val incrementalCache = state.incrementalCacheForThisTarget ?: return this.toList() val incrementalCache = state.incrementalCacheForThisTarget ?: return this.toList()
val moduleMappingData = incrementalCache.getModuleMappingData() ?: return this.toList() val moduleMappingData = incrementalCache.getModuleMappingData() ?: return this.toList()
val mapping = ModuleMapping.create(moduleMappingData, "<incremental>") val mapping = ModuleMapping.create(moduleMappingData, "<incremental>", state.deserializationConfiguration)
incrementalCache.getObsoletePackageParts().forEach { internalName -> incrementalCache.getObsoletePackageParts().forEach { internalName ->
val qualifier = internalName.substringBeforeLast('/', "").replace('/', '.') val qualifier = internalName.substringBeforeLast('/', "").replace('/', '.')
@@ -41,12 +41,10 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.BindingTraceFilter
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import java.io.File import java.io.File
@@ -94,6 +92,7 @@ class GenerationState @JvmOverloads constructor(
val incrementalCacheForThisTarget: IncrementalCache? val incrementalCacheForThisTarget: IncrementalCache?
val packagesWithObsoleteParts: Set<FqName> val packagesWithObsoleteParts: Set<FqName>
val obsoleteMultifileClasses: List<FqName> val obsoleteMultifileClasses: List<FqName>
val deserializationConfiguration: DeserializationConfiguration = CompilerDeserializationConfiguration(configuration)
init { init {
val icComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) val icComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.compiler.plugin.PluginCliOptionProcessingException
import org.jetbrains.kotlin.compiler.plugin.cliPluginUsageString import org.jetbrains.kotlin.compiler.plugin.cliPluginUsageString
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.script.StandardScriptDefinition import org.jetbrains.kotlin.script.StandardScriptDefinition
@@ -114,10 +113,6 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
return ExitCode.OK return ExitCode.OK
} }
if (arguments.skipMetadataVersionCheck) {
JvmMetadataVersion.skipCheck = true
}
if (arguments.includeRuntime) { if (arguments.includeRuntime) {
configuration.put(JVMConfigurationKeys.INCLUDE_RUNTIME, true) configuration.put(JVMConfigurationKeys.INCLUDE_RUNTIME, true)
} }
@@ -317,6 +312,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize) configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize)
configuration.put(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, arguments.inheritMultifileParts) configuration.put(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, arguments.inheritMultifileParts)
configuration.put(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK, arguments.skipRuntimeVersionCheck) configuration.put(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK, arguments.skipRuntimeVersionCheck)
configuration.put(CommonConfigurationKeys.SKIP_METADATA_VERSION_CHECK, arguments.skipMetadataVersionCheck)
configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage) configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
configuration.put(CLIConfigurationKeys.REPORT_PERF, arguments.reportPerf) configuration.put(CLIConfigurationKeys.REPORT_PERF, arguments.reportPerf)
configuration.put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule) configuration.put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.descriptors.PackagePartProvider import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.PackageParts import org.jetbrains.kotlin.load.kotlin.PackageParts
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import java.io.EOFException import java.io.EOFException
class JvmPackagePartProvider( class JvmPackagePartProvider(
@@ -32,6 +33,8 @@ class JvmPackagePartProvider(
) : PackagePartProvider { ) : PackagePartProvider {
private data class ModuleMappingInfo(val root: VirtualFile, val mapping: ModuleMapping) private data class ModuleMappingInfo(val root: VirtualFile, val mapping: ModuleMapping)
private val deserializationConfiguration = CompilerDeserializationConfiguration(env.configuration)
private val notLoadedRoots by lazy(LazyThreadSafetyMode.NONE) { private val notLoadedRoots by lazy(LazyThreadSafetyMode.NONE) {
env.configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS) env.configuration.getList(JVMConfigurationKeys.CONTENT_ROOTS)
.filterIsInstance<JvmClasspathRoot>() .filterIsInstance<JvmClasspathRoot>()
@@ -96,7 +99,7 @@ class JvmPackagePartProvider(
val moduleFiles = metaInf.children.filter { it.name.endsWith(ModuleMapping.MAPPING_FILE_EXT) } val moduleFiles = metaInf.children.filter { it.name.endsWith(ModuleMapping.MAPPING_FILE_EXT) }
for (moduleFile in moduleFiles) { for (moduleFile in moduleFiles) {
val mapping = try { val mapping = try {
ModuleMapping.create(moduleFile.contentsToByteArray(), moduleFile.toString()) ModuleMapping.create(moduleFile.contentsToByteArray(), moduleFile.toString(), deserializationConfiguration)
} }
catch (e: EOFException) { catch (e: EOFException) {
throw RuntimeException("Error on reading package parts for '$packageFqName' package in '$moduleFile', " + throw RuntimeException("Error on reading package parts for '$packageFqName' package in '$moduleFile', " +
@@ -19,18 +19,19 @@ package org.jetbrains.kotlin.load.kotlin.incremental
import org.jetbrains.kotlin.descriptors.PackagePartProvider import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
internal class IncrementalPackagePartProvider private constructor( internal class IncrementalPackagePartProvider(
private val parent: PackagePartProvider, private val parent: PackagePartProvider,
incrementalCaches: List<IncrementalCache>, incrementalCaches: List<IncrementalCache>,
storageManager: StorageManager storageManager: StorageManager
) : PackagePartProvider { ) : PackagePartProvider {
lateinit var deserializationConfiguration: DeserializationConfiguration
private val moduleMappings = storageManager.createLazyValue { private val moduleMappings = storageManager.createLazyValue {
incrementalCaches.map { cache -> incrementalCaches.map { cache ->
ModuleMapping.create(cache.getModuleMappingData(), "<incremental>") ModuleMapping.create(cache.getModuleMappingData(), "<incremental>", deserializationConfiguration)
} }
} }
@@ -41,19 +42,4 @@ internal class IncrementalPackagePartProvider private constructor(
// TODO // TODO
override fun findMetadataPackageParts(packageFqName: String): List<String> = TODO() override fun findMetadataPackageParts(packageFqName: String): List<String> = TODO()
companion object {
@JvmStatic
fun create(
parent: PackagePartProvider,
targets: List<TargetId>?,
incrementalCompilationComponents: IncrementalCompilationComponents?,
storageManager: StorageManager
): PackagePartProvider {
if (targets == null || incrementalCompilationComponents == null) return parent
val incrementalCaches = targets.map { incrementalCompilationComponents.getIncrementalCache(it) }
return IncrementalPackagePartProvider(parent, incrementalCaches, storageManager)
}
}
} }
@@ -63,6 +63,7 @@ import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtens
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import java.util.* import java.util.*
@@ -173,18 +174,22 @@ object TopDownAnalyzerFacadeForJVM {
} }
else null else null
val partProvider = packagePartProvider(sourceScope).let { fragment ->
if (targetIds == null || incrementalComponents == null) fragment
else IncrementalPackagePartProvider(fragment, targetIds.map(incrementalComponents::getIncrementalCache), storageManager)
}
// Note that it's necessary to create container for sources _after_ creation of container for dependencies because // Note that it's necessary to create container for sources _after_ creation of container for dependencies because
// CliLightClassGenerationSupport#initialize is invoked when container is created, so only the last module descriptor is going // CliLightClassGenerationSupport#initialize is invoked when container is created, so only the last module descriptor is going
// to be stored in CliLightClassGenerationSupport, and it better be the source one (otherwise light classes would not be found) // to be stored in CliLightClassGenerationSupport, and it better be the source one (otherwise light classes would not be found)
// TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport // TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport
val container = createContainerForTopDownAnalyzerForJvm( val container = createContainerForTopDownAnalyzerForJvm(
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker, moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker,
IncrementalPackagePartProvider.create( partProvider, languageVersionSettings, moduleClassResolver, configuration
packagePartProvider(sourceScope), targetIds, incrementalComponents, storageManager
),
languageVersionSettings, moduleClassResolver, configuration
).apply { ).apply {
initJvmBuiltInsForTopDownAnalysis(module, languageVersionSettings) initJvmBuiltInsForTopDownAnalysis(module, languageVersionSettings)
(partProvider as? IncrementalPackagePartProvider)?.deserializationConfiguration = get<DeserializationConfiguration>()
StorageComponentContainerContributor.getInstances(project).forEach { it.onContainerComposed(this, null) } StorageComponentContainerContributor.getInstances(project).forEach { it.onContainerComposed(this, null) }
} }
@@ -23,6 +23,9 @@ public class CommonConfigurationKeys {
public static final CompilerConfigurationKey<LanguageVersionSettings> LANGUAGE_VERSION_SETTINGS = public static final CompilerConfigurationKey<LanguageVersionSettings> LANGUAGE_VERSION_SETTINGS =
CompilerConfigurationKey.create("language version settings"); CompilerConfigurationKey.create("language version settings");
public static final CompilerConfigurationKey<Boolean> SKIP_METADATA_VERSION_CHECK =
CompilerConfigurationKey.create("skip metadata version check");
public static final CompilerConfigurationKey<Boolean> DISABLE_INLINE = public static final CompilerConfigurationKey<Boolean> DISABLE_INLINE =
CompilerConfigurationKey.create("disable inline"); CompilerConfigurationKey.create("disable inline");
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.frontend.di package org.jetbrains.kotlin.frontend.di
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.StorageComponentContainer
@@ -144,7 +145,9 @@ fun createContainerForLazyResolve(
useInstance(LookupTracker.DO_NOTHING) useInstance(LookupTracker.DO_NOTHING)
useInstance(languageVersionSettings) useInstance(languageVersionSettings)
//TODO: need to propagate full CompilerConfiguration to frontend //TODO: need to propagate full CompilerConfiguration to frontend
useInstance(CompilerConfiguration.EMPTY) useInstance(CompilerConfiguration().apply {
put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, languageVersionSettings)
})
useImpl<FileScopeProviderImpl>() useImpl<FileScopeProviderImpl>()
useImpl<CompilerDeserializationConfiguration>() useImpl<CompilerDeserializationConfiguration>()
@@ -16,11 +16,17 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
class CompilerDeserializationConfiguration(private val languageVersionSettings: LanguageVersionSettings) : DeserializationConfiguration { class CompilerDeserializationConfiguration(configuration: CompilerConfiguration) : DeserializationConfiguration {
override val typeAliasesAllowed: Boolean private val languageVersionSettings =
get() = languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases) configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, LanguageVersionSettingsImpl.DEFAULT)
override val typeAliasesAllowed = languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases)
override val skipMetadataVersionCheck = configuration.getBoolean(CommonConfigurationKeys.SKIP_METADATA_VERSION_CHECK)
} }
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.cli.AbstractCliTest
import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
import java.io.File import java.io.File
@@ -38,7 +39,10 @@ class JvmPackageTableTest : KtUsefulTestCase() {
System.err.println(output) // normally output is empty System.err.println(output) // normally output is empty
assertEquals("Compilation should complete successfully", ExitCode.OK, exitCode) assertEquals("Compilation should complete successfully", ExitCode.OK, exitCode)
val mapping = ModuleMapping.create(File(tmpdir, "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}").readBytes(), "test") val mapping = ModuleMapping.create(
File(tmpdir, "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}").readBytes(), "test",
DeserializationConfiguration.Default
)
val result = buildString { val result = buildString {
for ((fqName, packageParts) in mapping.packageFqName2Parts) { for ((fqName, packageParts) in mapping.packageFqName2Parts) {
appendln(fqName) appendln(fqName)
@@ -417,14 +417,9 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
doTestPreReleaseKotlinLibrary("library"); doTestPreReleaseKotlinLibrary("library");
} }
/*
// This test should pass but is commented out because the compiler flag is implemented via mutation of the public field,
// which may cause subsequent tests to behave unexpectedly
// TODO: refactor and uncomment
public void testReleaseCompilerAgainstPreReleaseLibrarySkipVersionCheck() throws Exception { public void testReleaseCompilerAgainstPreReleaseLibrarySkipVersionCheck() throws Exception {
doTestPreReleaseKotlinLibrary("library", "-Xskip-metadata-version-check"); doTestPreReleaseKotlinLibrary("library", "-Xskip-metadata-version-check");
} }
*/
public void testWrongMetadataVersion() throws Exception { public void testWrongMetadataVersion() throws Exception {
doTestKotlinLibraryWithWrongMetadataVersion("library", null); doTestKotlinLibraryWithWrongMetadataVersion("library", null);
@@ -466,12 +461,9 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
); );
} }
/*
// TODO: refactor and uncomment
public void testWrongMetadataVersionSkipVersionCheck() throws Exception { public void testWrongMetadataVersionSkipVersionCheck() throws Exception {
doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-metadata-version-check"); doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-metadata-version-check");
} }
*/
/*test source mapping generation when source info is absent*/ /*test source mapping generation when source info is absent*/
public void testInlineFunWithoutDebugInfo() throws Exception { public void testInlineFunWithoutDebugInfo() throws Exception {
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.serialization.deserialization.DeserializationCompone
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
import org.jetbrains.kotlin.utils.addToStdlib.check
import javax.inject.Inject import javax.inject.Inject
class DeserializedDescriptorResolver { class DeserializedDescriptorResolver {
@@ -39,6 +38,9 @@ class DeserializedDescriptorResolver {
this.components = components.components this.components = components.components
} }
private val skipMetadataVersionCheck: Boolean
get() = components.configuration.skipMetadataVersionCheck
fun resolveClass(kotlinClass: KotlinJvmBinaryClass): ClassDescriptor? { fun resolveClass(kotlinClass: KotlinJvmBinaryClass): ClassDescriptor? {
val classData = readClassData(kotlinClass) ?: return null val classData = readClassData(kotlinClass) ?: return null
return components.classDeserializer.deserializeClass(kotlinClass.classId, classData) return components.classDeserializer.deserializeClass(kotlinClass.classId, classData)
@@ -69,18 +71,18 @@ class DeserializedDescriptorResolver {
private val KotlinJvmBinaryClass.incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>? private val KotlinJvmBinaryClass.incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>?
get() { get() {
if (classHeader.metadataVersion.isCompatible()) return null if (skipMetadataVersionCheck || classHeader.metadataVersion.isCompatible()) return null
return IncompatibleVersionErrorData(classHeader.metadataVersion, JvmMetadataVersion.INSTANCE, location, classId) return IncompatibleVersionErrorData(classHeader.metadataVersion, JvmMetadataVersion.INSTANCE, location, classId)
} }
private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean
get() = !JvmMetadataVersion.skipCheck && get() = !skipMetadataVersionCheck &&
!KotlinCompilerVersion.isPreRelease() && !KotlinCompilerVersion.isPreRelease() &&
(classHeader.isPreRelease || classHeader.metadataVersion == KOTLIN_1_1_EAP_METADATA_VERSION) (classHeader.isPreRelease || classHeader.metadataVersion == KOTLIN_1_1_EAP_METADATA_VERSION)
internal fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set<KotlinClassHeader.Kind>): Array<String>? { internal fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set<KotlinClassHeader.Kind>): Array<String>? {
val header = kotlinClass.classHeader val header = kotlinClass.classHeader
return (header.data ?: header.incompatibleData)?.check { header.kind in expectedKinds } return (header.data ?: header.incompatibleData)?.takeIf { header.kind in expectedKinds }
} }
private inline fun <T : Any> parseProto(klass: KotlinJvmBinaryClass, block: () -> T): T? { private inline fun <T : Any> parseProto(klass: KotlinJvmBinaryClass, block: () -> T): T? {
@@ -93,11 +95,12 @@ class DeserializedDescriptorResolver {
} }
} }
catch (e: Throwable) { catch (e: Throwable) {
if (!klass.classHeader.metadataVersion.isCompatible()) { if (skipMetadataVersionCheck || klass.classHeader.metadataVersion.isCompatible()) {
// TODO: log.warn throw e
return null
} }
throw e
// TODO: log.warn
return null
} }
} }
@@ -25,12 +25,9 @@ import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
class JvmMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) { class JvmMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
// NOTE: 1.1 is incompatible with 1.0 and hence with any other version except 1.1.* // NOTE: 1.1 is incompatible with 1.0 and hence with any other version except 1.1.*
override fun isCompatible() = override fun isCompatible() =
skipCheck || (this.major == 1 && this.minor == 1) this.major == 1 && this.minor == 1
companion object { companion object {
// TODO: this is a temporary hack which can be removed once we migrate the IDEA code from 1.0 to 1.1
var skipCheck: Boolean = false
@JvmField @JvmField
val INSTANCE = JvmMetadataVersion(1, 1, 5) val INSTANCE = JvmMetadataVersion(1, 1, 5)
@@ -16,10 +16,10 @@
package org.jetbrains.kotlin.load.kotlin package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.DataInputStream import java.io.DataInputStream
import kotlin.comparisons.nullsLast
class ModuleMapping private constructor(val packageFqName2Parts: Map<String, PackageParts>, private val debugName: String) { class ModuleMapping private constructor(val packageFqName2Parts: Map<String, PackageParts>, private val debugName: String) {
fun findPackageParts(packageFqName: String): PackageParts? { fun findPackageParts(packageFqName: String): PackageParts? {
@@ -35,7 +35,11 @@ class ModuleMapping private constructor(val packageFqName2Parts: Map<String, Pac
@JvmField @JvmField
val EMPTY: ModuleMapping = ModuleMapping(emptyMap(), "EMPTY") val EMPTY: ModuleMapping = ModuleMapping(emptyMap(), "EMPTY")
fun create(bytes: ByteArray?, debugName: String?): ModuleMapping { fun create(
bytes: ByteArray?,
debugName: String,
configuration: DeserializationConfiguration
): ModuleMapping {
if (bytes == null) { if (bytes == null) {
return EMPTY return EMPTY
} }
@@ -43,7 +47,7 @@ class ModuleMapping private constructor(val packageFqName2Parts: Map<String, Pac
val stream = DataInputStream(ByteArrayInputStream(bytes)) val stream = DataInputStream(ByteArrayInputStream(bytes))
val version = JvmMetadataVersion(*IntArray(stream.readInt()) { stream.readInt() }) val version = JvmMetadataVersion(*IntArray(stream.readInt()) { stream.readInt() })
if (version.isCompatible()) { if (configuration.skipMetadataVersionCheck || version.isCompatible()) {
val table = JvmPackageTable.PackageTable.parseFrom(stream) ?: return EMPTY val table = JvmPackageTable.PackageTable.parseFrom(stream) ?: return EMPTY
val result = linkedMapOf<String, PackageParts>() val result = linkedMapOf<String, PackageParts>()
@@ -60,7 +64,7 @@ class ModuleMapping private constructor(val packageFqName2Parts: Map<String, Pac
proto.classNameList.forEach(packageParts::addMetadataPart) proto.classNameList.forEach(packageParts::addMetadataPart)
} }
return ModuleMapping(result, debugName ?: "<unknown>") return ModuleMapping(result, debugName)
} }
else { else {
// TODO: consider reporting "incompatible ABI version" error for package parts // TODO: consider reporting "incompatible ABI version" error for package parts
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.kotlin.reflect
import org.jetbrains.kotlin.descriptors.PackagePartProvider import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
class RuntimePackagePartProvider(private val classLoader: ClassLoader) : PackagePartProvider { class RuntimePackagePartProvider(private val classLoader: ClassLoader) : PackagePartProvider {
@@ -27,7 +28,7 @@ class RuntimePackagePartProvider(private val classLoader: ClassLoader) : Package
val mapping = try { val mapping = try {
val resourcePath = "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}" val resourcePath = "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}"
classLoader.getResourceAsStream(resourcePath)?.use { stream -> classLoader.getResourceAsStream(resourcePath)?.use { stream ->
ModuleMapping.create(stream.readBytes(), resourcePath) ModuleMapping.create(stream.readBytes(), resourcePath, DeserializationConfiguration.Default)
} }
} }
catch (e: Exception) { catch (e: Exception) {
@@ -17,6 +17,9 @@
package org.jetbrains.kotlin.serialization.deserialization package org.jetbrains.kotlin.serialization.deserialization
interface DeserializationConfiguration { interface DeserializationConfiguration {
val skipMetadataVersionCheck: Boolean
get() = false
val typeAliasesAllowed: Boolean val typeAliasesAllowed: Boolean
get() = true get() = true
@@ -22,6 +22,7 @@ import com.intellij.util.io.IOUtil
import com.intellij.util.io.KeyDescriptor import com.intellij.util.io.KeyDescriptor
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.PackageParts import org.jetbrains.kotlin.load.kotlin.PackageParts
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import java.io.DataInput import java.io.DataInput
import java.io.DataOutput import java.io.DataOutput
@@ -77,7 +78,7 @@ object KotlinModuleMappingIndex : FileBasedIndexExtension<String, PackageParts>(
val content = inputData.content val content = inputData.content
val file = inputData.file val file = inputData.file
try { try {
val moduleMapping = ModuleMapping.create(content, file.toString()) val moduleMapping = ModuleMapping.create(content, file.toString(), DeserializationConfiguration.Default)
return@DataIndexer moduleMapping.packageFqName2Parts return@DataIndexer moduleMapping.packageFqName2Parts
} }
catch(e: Exception) { catch(e: Exception) {
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.config.CommonConfigurationKeys; import org.jetbrains.kotlin.config.CommonConfigurationKeys;
import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider; import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.kotlin.js.resolve.JsPlatform; import org.jetbrains.kotlin.js.resolve.JsPlatform;
@@ -129,9 +128,7 @@ public abstract class JsConfig {
); );
JsModuleDescriptor<PackageFragmentProvider> rawDescriptor = KotlinJavascriptSerializationUtil.readModule( JsModuleDescriptor<PackageFragmentProvider> rawDescriptor = KotlinJavascriptSerializationUtil.readModule(
metadata.getBody(), storageManager, moduleDescriptor, new CompilerDeserializationConfiguration( metadata.getBody(), storageManager, moduleDescriptor, new CompilerDeserializationConfiguration(configuration)
configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, LanguageVersionSettingsImpl.DEFAULT)
)
); );
PackageFragmentProvider provider = rawDescriptor.getData(); PackageFragmentProvider provider = rawDescriptor.getData();