Minimize dependencies of ModuleMapping

Prepare it to be moved to metadata.jvm
This commit is contained in:
Alexander Udalov
2018-03-14 14:10:07 +01:00
parent 6b800c4230
commit d0544a148a
11 changed files with 59 additions and 34 deletions
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorUtilKt;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor; import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.kotlin.ModuleMapping; import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.ModuleMappingUtilKt;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackageParts; import org.jetbrains.kotlin.load.kotlin.PackageParts;
import org.jetbrains.kotlin.metadata.ProtoBuf; import org.jetbrains.kotlin.metadata.ProtoBuf;
@@ -192,8 +193,9 @@ public class ClassFileFactory implements OutputFileCollection {
answer.append(file.asText()); answer.append(file.asText());
break; break;
case "kotlin_module": { case "kotlin_module": {
ModuleMapping mapping = ModuleMapping.Companion.create( ModuleMapping mapping = ModuleMappingUtilKt.loadModuleMapping(
file.asByteArray(), relativePath.getPath(), CompilerDeserializationConfiguration.Default.INSTANCE ModuleMapping.Companion, file.asByteArray(), relativePath.getPath(),
CompilerDeserializationConfiguration.Default.INSTANCE
); );
for (Map.Entry<String, PackageParts> entry : mapping.getPackageFqName2Parts().entrySet()) { for (Map.Entry<String, PackageParts> entry : mapping.getPackageFqName2Parts().entrySet()) {
FqName packageFqName = new FqName(entry.getKey()); FqName packageFqName = new FqName(entry.getKey());
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
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.load.kotlin.loadModuleMapping
import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
@@ -41,7 +42,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>", state.deserializationConfiguration) val mapping = ModuleMapping.loadModuleMapping(moduleMappingData, "<incremental>", state.deserializationConfiguration)
incrementalCache.getObsoletePackageParts().forEach { internalName -> incrementalCache.getObsoletePackageParts().forEach { internalName ->
val qualifier = JvmClassName.byInternalName(internalName).packageFqName.asString() val qualifier = JvmClassName.byInternalName(internalName).packageFqName.asString()
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
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.load.kotlin.loadModuleMapping
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import java.io.EOFException import java.io.EOFException
@@ -71,7 +72,7 @@ class JvmPackagePartProvider(
override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> { override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> {
return loadedModules.mapNotNull { (_, mapping, name) -> return loadedModules.mapNotNull { (_, mapping, name) ->
if (name == moduleName) mapping.moduleData.annotations else null if (name == moduleName) mapping.moduleData.annotations.map(ClassId::fromString) else null
}.flatten() }.flatten()
} }
@@ -85,9 +86,8 @@ class JvmPackagePartProvider(
if (!moduleFile.name.endsWith(ModuleMapping.MAPPING_FILE_EXT)) continue if (!moduleFile.name.endsWith(ModuleMapping.MAPPING_FILE_EXT)) continue
val mapping = try { val mapping = try {
ModuleMapping.create(moduleFile.contentsToByteArray(), moduleFile.toString(), deserializationConfiguration) ModuleMapping.loadModuleMapping(moduleFile.contentsToByteArray(), moduleFile.toString(), deserializationConfiguration)
} } catch (e: EOFException) {
catch (e: EOFException) {
throw RuntimeException("Error on reading package parts from $moduleFile in $root", e) throw RuntimeException("Error on reading package parts from $moduleFile in $root", e)
} }
loadedModules.add(ModuleMappingInfo(root, mapping, moduleFile.nameWithoutExtension)) loadedModules.add(ModuleMappingInfo(root, mapping, moduleFile.nameWithoutExtension))
@@ -19,6 +19,7 @@ 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.loadModuleMapping
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
@@ -32,7 +33,7 @@ class IncrementalPackagePartProvider(
private val moduleMappings = storageManager.createLazyValue { private val moduleMappings = storageManager.createLazyValue {
incrementalCaches.map { cache -> incrementalCaches.map { cache ->
ModuleMapping.create(cache.getModuleMappingData(), "<incremental>", deserializationConfiguration) ModuleMapping.loadModuleMapping(cache.getModuleMappingData(), "<incremental>", deserializationConfiguration)
} }
} }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.loadModuleMapping
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.test.CompilerTestUtil import org.jetbrains.kotlin.test.CompilerTestUtil
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
@@ -45,7 +46,7 @@ class JvmModuleProtoBufTest : KtUsefulTestCase() {
"-language-version", compileWith.versionString "-language-version", compileWith.versionString
) + extraOptions) ) + extraOptions)
val mapping = ModuleMapping.create( val mapping = ModuleMapping.loadModuleMapping(
File(tmpdir, "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}").readBytes(), "test", File(tmpdir, "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}").readBytes(), "test",
CompilerDeserializationConfiguration( CompilerDeserializationConfiguration(
LanguageVersionSettingsImpl(loadWith, ApiVersion.createByLanguageVersion(loadWith)) LanguageVersionSettingsImpl(loadWith, ApiVersion.createByLanguageVersion(loadWith))
@@ -53,7 +54,7 @@ class JvmModuleProtoBufTest : KtUsefulTestCase() {
) )
val result = buildString { val result = buildString {
for (annotationClassId in mapping.moduleData.annotations) { for (annotationClassId in mapping.moduleData.annotations) {
appendln("@${annotationClassId.asString()}") appendln("@$annotationClassId")
} }
for ((fqName, packageParts) in mapping.packageFqName2Parts) { for ((fqName, packageParts) in mapping.packageFqName2Parts) {
appendln(fqName) appendln(fqName)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.load.kotlin package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.name.ClassId /**
* @param annotations list of module annotations, in the format: "org/foo/bar/Baz.Inner" (see [ClassId.fromString])
class BinaryModuleData(val annotations: List<ClassId>) */
class BinaryModuleData(val annotations: List<String>)
@@ -18,11 +18,6 @@ package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.DataInputStream import java.io.DataInputStream
import java.io.IOException import java.io.IOException
@@ -48,10 +43,12 @@ class ModuleMapping private constructor(
@JvmField @JvmField
val CORRUPTED: ModuleMapping = ModuleMapping(emptyMap(), BinaryModuleData(emptyList()), "CORRUPTED") val CORRUPTED: ModuleMapping = ModuleMapping(emptyMap(), BinaryModuleData(emptyList()), "CORRUPTED")
fun create( fun loadModuleMapping(
bytes: ByteArray?, bytes: ByteArray?,
debugName: String, debugName: String,
configuration: DeserializationConfiguration isVersionCompatible: (IntArray) -> Boolean,
skipMetadataVersionCheck: Boolean,
isJvmPackageNameSupported: Boolean
): ModuleMapping { ): ModuleMapping {
if (bytes == null) { if (bytes == null) {
return EMPTY return EMPTY
@@ -66,9 +63,7 @@ class ModuleMapping private constructor(
return CORRUPTED return CORRUPTED
} }
val version = JvmMetadataVersion(*versionNumber) if (skipMetadataVersionCheck || isVersionCompatible(versionNumber)) {
if (configuration.skipMetadataVersionCheck || version.isCompatible()) {
val moduleProto = JvmModuleProtoBuf.Module.parseFrom(stream) ?: return EMPTY val moduleProto = JvmModuleProtoBuf.Module.parseFrom(stream) ?: return EMPTY
val result = linkedMapOf<String, PackageParts>() val result = linkedMapOf<String, PackageParts>()
@@ -83,7 +78,7 @@ class ModuleMapping private constructor(
packageParts.addPart(internalNameOf(packageFqName, partShortName), facadeInternalName) packageParts.addPart(internalNameOf(packageFqName, partShortName), facadeInternalName)
} }
if (configuration.isJvmPackageNameSupported) { if (isJvmPackageNameSupported) {
for ((index, partShortName) in proto.classWithJvmPackageNameShortNameList.withIndex()) { for ((index, partShortName) in proto.classWithJvmPackageNameShortNameList.withIndex()) {
val packageId = proto.classWithJvmPackageNamePackageIdList.getOrNull(index) val packageId = proto.classWithJvmPackageNamePackageIdList.getOrNull(index)
?: proto.classWithJvmPackageNamePackageIdList.lastOrNull() ?: proto.classWithJvmPackageNamePackageIdList.lastOrNull()
@@ -101,7 +96,7 @@ class ModuleMapping private constructor(
// TODO: read arguments of module annotations // TODO: read arguments of module annotations
val nameResolver = NameResolverImpl(moduleProto.stringTable, moduleProto.qualifiedNameTable) val nameResolver = NameResolverImpl(moduleProto.stringTable, moduleProto.qualifiedNameTable)
val annotations = moduleProto.annotationList.map { proto -> nameResolver.getClassId(proto.id) } val annotations = moduleProto.annotationList.map { proto -> nameResolver.getQualifiedClassName(proto.id) }
return ModuleMapping(result, BinaryModuleData(annotations), debugName) return ModuleMapping(result, BinaryModuleData(annotations), debugName)
} else { } else {
@@ -114,7 +109,8 @@ class ModuleMapping private constructor(
} }
private fun internalNameOf(packageFqName: String, className: String): String = private fun internalNameOf(packageFqName: String, className: String): String =
JvmClassName.byFqNameWithoutInnerClasses(FqName(packageFqName).child(Name.identifier(className))).internalName if (packageFqName.isEmpty()) className
else packageFqName.replace('.', '/') + "/" + className
class PackageParts(val packageFqName: String) { class PackageParts(val packageFqName: String) {
// JVM internal name of package part -> JVM internal name of the corresponding multifile facade (or null, if it's not a multifile part) // JVM internal name of package part -> JVM internal name of the corresponding multifile facade (or null, if it's not a multifile part)
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
fun ModuleMapping.Companion.loadModuleMapping(
bytes: ByteArray?,
debugName: String,
configuration: DeserializationConfiguration
): ModuleMapping =
loadModuleMapping(
bytes,
debugName,
{ version -> JvmMetadataVersion(*version).isCompatible() },
configuration.skipMetadataVersionCheck,
configuration.isJvmPackageNameSupported
)
@@ -18,6 +18,7 @@ package kotlin.reflect.jvm.internal.components
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.loadModuleMapping
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -29,10 +30,9 @@ 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, DeserializationConfiguration.Default) ModuleMapping.loadModuleMapping(stream.readBytes(), resourcePath, DeserializationConfiguration.Default)
} }
} } catch (e: Exception) {
catch (e: Exception) {
// TODO: do not swallow this exception? // TODO: do not swallow this exception?
null null
} }
@@ -9,6 +9,7 @@ import com.intellij.util.indexing.*
import com.intellij.util.io.DataExternalizer import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.IOUtil import com.intellij.util.io.IOUtil
import org.jetbrains.kotlin.load.kotlin.ModuleMapping import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.loadModuleMapping
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import java.io.DataInput import java.io.DataInput
@@ -44,8 +45,8 @@ object KotlinJvmModuleAnnotationsIndex : FileBasedIndexExtension<String, List<Cl
override fun getIndexer(): DataIndexer<String, List<ClassId>, FileContent> = DataIndexer { inputData -> override fun getIndexer(): DataIndexer<String, List<ClassId>, FileContent> = DataIndexer { inputData ->
val file = inputData.file val file = inputData.file
try { try {
val moduleMapping = ModuleMapping.create(inputData.content, file.toString(), DeserializationConfiguration.Default) val moduleMapping = ModuleMapping.loadModuleMapping(inputData.content, file.toString(), DeserializationConfiguration.Default)
return@DataIndexer mapOf(file.nameWithoutExtension to moduleMapping.moduleData.annotations) return@DataIndexer mapOf(file.nameWithoutExtension to moduleMapping.moduleData.annotations.map(ClassId::fromString))
} catch (e: Exception) { } catch (e: Exception) {
// Exceptions are already reported in KotlinModuleMappingIndex // Exceptions are already reported in KotlinModuleMappingIndex
emptyMap() emptyMap()
@@ -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.load.kotlin.loadModuleMapping
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration 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(), DeserializationConfiguration.Default) val moduleMapping = ModuleMapping.loadModuleMapping(content, file.toString(), DeserializationConfiguration.Default)
if (moduleMapping === ModuleMapping.CORRUPTED) { if (moduleMapping === ModuleMapping.CORRUPTED) {
file.refresh(true, false) file.refresh(true, false)
} }