Store source file info in klib. (#2243)

This commit is contained in:
Nikolay Igotti
2018-10-24 11:40:54 +03:00
committed by GitHub
parent b32a73bbf1
commit 17cf1df4f4
9 changed files with 132 additions and 15 deletions
@@ -7,12 +7,21 @@ package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.backend.konan.binaryTypeIsReference
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.irasdescriptors.ClassDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.ConstructorDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.DeclarationDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.FunctionDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.backend.konan.irasdescriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.konan.isInlined
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
import org.jetbrains.kotlin.types.SimpleType
/**
@@ -231,3 +240,22 @@ tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescrip
fun FunctionDescriptor.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean =
this in map.values
private fun sourceByIndex(descriptor: CallableMemberDescriptor, index: Int): SourceFile {
val fragment = descriptor.findPackage() as KonanPackageFragment
return fragment.sourceFileMap.sourceFile(index)
}
fun CallableMemberDescriptor.findSourceFile(): SourceFile {
val source = this.source.containingFile
if (source != SourceFile.NO_SOURCE_FILE)
return source
return when {
this is DeserializedSimpleFunctionDescriptor && proto.hasExtension(KonanProtoBuf.functionFile) -> sourceByIndex(
this, proto.getExtension(KonanProtoBuf.functionFile))
this is DeserializedPropertyDescriptor && proto.hasExtension(KonanProtoBuf.propertyFile) ->
sourceByIndex(
this, proto.getExtension(KonanProtoBuf.propertyFile))
else -> TODO()
}
}
@@ -26,7 +26,7 @@ interface KonanLibraryWriter {
class LinkData(
val module: ByteArray,
val fragments: List<List<ByteArray>>,
val fragmentNames: List<String>
val fragmentNames: List<String>
)
interface MetadataWriter {
@@ -193,7 +193,7 @@ abstract class ObjCExportHeaderGenerator(
if (classDescriptor != null) {
extensions.getOrPut(classDescriptor, { mutableListOf() }) += it
} else {
topLevel.getOrPut(it.source.containingFile, { mutableListOf() }) += it
topLevel.getOrPut(it.findSourceFile(), { mutableListOf() }) += it
}
}
@@ -13,14 +13,13 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter.Companion.CALLABLES
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter.Companion.CLASSIFIERS
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
import org.jetbrains.kotlin.serialization.konan.SourceFileMap
/*
* This is Konan specific part of public descriptor
@@ -37,6 +36,8 @@ internal class KonanSerializationUtil(val context: Context, private val metadata
lateinit var serializerContext: SerializerContext
val sourceFileMap = SourceFileMap()
data class SerializerContext(
val serializerExtension: KonanSerializerExtension,
val topSerializer: KonanDescriptorSerializer,
@@ -44,7 +45,7 @@ internal class KonanSerializationUtil(val context: Context, private val metadata
)
private fun createNewContext(): SerializerContext {
val extension = KonanSerializerExtension(context, metadataVersion)
val extension = KonanSerializerExtension(context, metadataVersion, sourceFileMap)
return SerializerContext(
extension,
KonanDescriptorSerializer.createTopLevel(context, extension)
@@ -213,7 +214,8 @@ internal class KonanSerializationUtil(val context: Context, private val metadata
val fragmentNames = mutableListOf<String>()
getPackagesFqNames(moduleDescriptor).forEach iteration@{ packageFqName ->
val packageProtos = serializePackage(packageFqName, moduleDescriptor)
val packageProtos =
serializePackage(packageFqName, moduleDescriptor)
if (packageProtos.isEmpty()) return@iteration
val packageFqNameStr = packageFqName.asString()
@@ -223,7 +225,13 @@ internal class KonanSerializationUtil(val context: Context, private val metadata
}
fragments.add(packageProtos.map { it.toByteArray() })
fragmentNames.add(packageFqNameStr)
}
sourceFileMap.filesAndClear().map { it.name ?: "" }.forEach {
libraryProto.addFile(it)
}
val libraryAsByteArray = libraryProto.build().toByteArray()
return LinkData(libraryAsByteArray, fragments, fragmentNames)
}
@@ -16,9 +16,11 @@ import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTabl
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
import org.jetbrains.kotlin.serialization.konan.SourceFileMap
import org.jetbrains.kotlin.types.KotlinType
internal class KonanSerializerExtension(val context: Context, override val metadataVersion: BinaryVersion) :
internal class KonanSerializerExtension(val context: Context, override val metadataVersion: BinaryVersion,
val sourceFileMap: SourceFileMap) :
KotlinSerializerExtensionBase(KonanSerializerProtocol), IrAwareExtension {
val inlineDescriptorTable = DescriptorTable(context.irBuiltIns)
@@ -28,7 +30,7 @@ internal class KonanSerializerExtension(val context: Context, override val metad
override fun serializeType(type: KotlinType, proto: ProtoBuf.Type.Builder) {
// TODO: For debugging purpose we store the textual
// representation of serialized types.
// To be removed for release 1.0.
// To be removed.
proto.setExtension(KonanProtoBuf.typeText, type.toString())
super.serializeType(type, proto)
@@ -60,7 +62,7 @@ internal class KonanSerializerExtension(val context: Context, override val metad
}
override fun serializeFunction(descriptor: FunctionDescriptor, proto: ProtoBuf.Function.Builder) {
proto.setExtension(KonanProtoBuf.functionFile, sourceFileMap.assign(descriptor.source.containingFile))
super.serializeFunction(descriptor, proto)
}
@@ -69,7 +71,7 @@ internal class KonanSerializerExtension(val context: Context, override val metad
if (variable != null) {
proto.setExtension(KonanProtoBuf.usedAsVariable, true)
}
proto.setExtension(KonanProtoBuf.propertyFile, sourceFileMap.assign(descriptor.source.containingFile))
proto.setExtension(KonanProtoBuf.hasBackingField,
context.ir.propertiesWithBackingFields.contains(descriptor))
@@ -32,6 +32,7 @@ extend Constructor {
extend Function {
repeated Annotation function_annotation = 170;
optional InlineIrBody inline_ir_body = 171;
optional int32 function_file = 172;
}
extend Property {
@@ -41,6 +42,7 @@ extend Property {
optional Annotation.Argument.Value compile_time_value = 173;
optional InlineIrBody inline_getter_ir_body = 174;
optional InlineIrBody inline_setter_ir_body = 175;
optional int32 property_file = 176;
}
extend EnumEntry {
@@ -95,5 +97,6 @@ message LinkDataLibrary {
required string module_name = 1;
repeated string package_fragment_name = 2;
repeated string empty_package = 3;
repeated string file = 4;
}
@@ -2,11 +2,10 @@ package org.jetbrains.kotlin.konan.library.resolver.impl
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
import org.jetbrains.kotlin.serialization.konan.SourceFileMap
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
internal class KonanResolvedLibraryImpl(
override val library: KonanLibrary
): KonanResolvedLibrary {
internal class KonanResolvedLibraryImpl(override val library: KonanLibrary): KonanResolvedLibrary {
private val _resolvedDependencies = mutableListOf<KonanResolvedLibrary>()
private val _emptyPackages by lazy { parseModuleHeader(library.moduleHeaderData).emptyPackageList }
@@ -1,8 +1,15 @@
/*
* 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 file.
*/
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
import org.jetbrains.kotlin.konan.library.resolver.impl.KonanResolvedLibraryImpl
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.FqName
@@ -14,6 +21,17 @@ import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.storage.StorageManager
private val KonanLibrary.fileSources: SourceFileMap get() {
val result = SourceFileMap()
val proto = parseModuleHeader(moduleHeaderData)
proto.fileList.forEachIndexed { index, it ->
result.provide(it, index, this)
}
return result
}
class KonanPackageFragment(
fqName: FqName,
private val library: KonanLibrary,
@@ -23,6 +41,10 @@ class KonanPackageFragment(
partName: String
) : DeserializedPackageFragment(fqName, storageManager, module) {
val sourceFileMap: SourceFileMap by lazy {
library.fileSources
}
lateinit var components: DeserializationComponents
override fun initialize(components: DeserializationComponents) {
@@ -0,0 +1,55 @@
/*
* 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 file.
*/
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragment
private class DeserializedSourceFile(
val name_: String, val index: Int, val library: KonanLibrary) : SourceFile {
override fun getName(): String? = name_
override fun equals(other: Any?): Boolean {
return other is DeserializedSourceFile && library == other.library && index == other.index
}
override fun hashCode(): Int {
return library.hashCode() xor index
}
}
class SourceFileMap {
private val sourceToIndex = mutableMapOf<SourceFile, Int>()
private val indexToSource = mutableMapOf<Int, SourceFile>()
fun assign(file: SourceFile): Int {
return sourceToIndex.getOrPut(file) {
sourceToIndex.size
}
}
fun provide(fileName: String, index: Int, library: KonanLibrary) {
assert(indexToSource[index] == null)
indexToSource[index] = DeserializedSourceFile(fileName, index, library)
}
fun sourceFile(index: Int): SourceFile =
indexToSource[index] ?: throw Error("Unknown file for $index")
fun filesAndClear() =
sourceToIndex.keys.sortedBy {
sourceToIndex[it]
}.also{
clear()
}
fun clear() {
sourceToIndex.clear()
indexToSource.clear()
}
}