Deserialization code clean up

This commit is contained in:
Roman Artemev
2019-02-27 19:32:15 +03:00
committed by romanart
parent d085e66aa3
commit 3770d310f1
13 changed files with 48 additions and 426 deletions
@@ -133,8 +133,8 @@ fun compile(
?: JsKlibMetadataVersion.INSTANCE ?: JsKlibMetadataVersion.INSTANCE
val lookupTracker = LookupTracker.DO_NOTHING val lookupTracker = LookupTracker.DO_NOTHING
val languageSettings = configuration.languageVersionSettings val languageSettings = configuration.languageVersionSettings
val storageManeger = LockBasedStorageManager("JsDepencencies") val storageManager = LockBasedStorageManager("JsDependencies")
val dfsHandler: MetadataDFSHandler = DependencyMetadataLoader(lookupTracker, metadataVersion, languageSettings, storageManeger) val dfsHandler: MetadataDFSHandler = DependencyMetadataLoader(lookupTracker, metadataVersion, languageSettings, storageManager)
val sortedDeps = DFS.dfs(dependencies, CompiledModule::dependencies, dfsHandler) val sortedDeps = DFS.dfs(dependencies, CompiledModule::dependencies, dfsHandler)
val builtInModule = sortedDeps.firstOrNull()?.moduleDescriptor // null in case compiling builtInModule itself val builtInModule = sortedDeps.firstOrNull()?.moduleDescriptor // null in case compiling builtInModule itself
@@ -219,6 +219,7 @@ fun compile(
).generateUnboundSymbolsAsDependencies(it) ).generateUnboundSymbolsAsDependencies(it)
} }
// TODO: check the order
val irFiles = deserializedModuleFragments.flatMap { it.files } + moduleFragment.files val irFiles = deserializedModuleFragments.flatMap { it.files } + moduleFragment.files
moduleFragment.files.clear() moduleFragment.files.clear()
@@ -5,33 +5,16 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.SourceManager import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.isMarkedNullable
import org.jetbrains.kotlin.ir.util.explicitParameters
import org.jetbrains.kotlin.ir.util.isFunction
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.isSuspendFunction
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
val IrConstructor.constructedClass get() = this.parent as IrClass val IrConstructor.constructedClass get() = this.parent as IrClass
val <T : IrDeclaration> T.original get() = this val <T : IrDeclaration> T.original get() = this
val IrDeclaration.containingDeclaration get() = this.parent
val IrDeclarationParent.fqNameSafe: FqName val IrDeclarationParent.fqNameSafe: FqName
get() = when (this) { get() = when (this) {
@@ -67,79 +50,12 @@ val IrDeclaration.name: Name
private val SPECIAL_INIT_NAME = Name.special("<init>") private val SPECIAL_INIT_NAME = Name.special("<init>")
val IrField.fqNameSafe: FqName get() = this.parent.fqNameSafe.child(this.name)
/**
* @return naturally-ordered list of all parameters available inside the function body.
*/
val IrFunction.allParameters: List<IrValueParameter>
get() = if (this is IrConstructor) {
listOf(this.constructedClass.thisReceiver
?: error(this.descriptor)
) + explicitParameters
} else {
explicitParameters
}
val IrValueParameter.isVararg get() = this.varargElementType != null val IrValueParameter.isVararg get() = this.varargElementType != null
val IrFunction.isSuspend get() = this is IrSimpleFunction && this.isSuspend val IrFunction.isSuspend get() = this is IrSimpleFunction && this.isSuspend
fun IrClass.isUnit() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.unit.toSafe()
fun IrClass.isKotlinArray() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.array.toSafe()
val IrClass.superClasses get() = this.superTypes.map { it.classifierOrFail as IrClassSymbol }
fun IrClass.getSuperClassNotAny() = this.superClasses.map { it.owner }.atMostOne { !it.isInterface && !it.isAny() }
fun IrClass.isAny() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.any.toSafe()
fun IrClass.isNothing() = this.fqNameSafe == KotlinBuiltIns.FQ_NAMES.nothing.toSafe()
fun IrClass.getSuperInterfaces() = this.superClasses.map { it.owner }.filter { it.isInterface }
val IrProperty.konanBackingField: IrField?
get() {
assert(this.isReal)
this.backingField?.let { return it }
// (this.descriptor as? DeserializedPropertyDescriptor)?.konanBackingField?.let { backingFieldDescriptor ->
// val result = IrFieldImpl(
// this.startOffset,
// this.endOffset,
// IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
// backingFieldDescriptor,
// this.getter!!.returnType
// ).also {
// it.parent = this.parent
// }
// this.backingField = result
// return result
// }
return null
}
val IrField.containingClass get() = this.parent as? IrClass
val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE
// Note: psi2ir doesn't set `origin = FAKE_OVERRIDE` for fields and properties yet.
val IrProperty.isReal: Boolean get() = this.descriptor.kind.isReal
val IrField.isReal: Boolean get() = this.descriptor.kind.isReal
val IrSimpleFunction.isOverridable: Boolean
get() = visibility != Visibilities.PRIVATE
&& modality != Modality.FINAL
&& (parent as? IrClass)?.isFinalClass != true
val IrFunction.isOverridable get() = this is IrSimpleFunction && this.isOverridable
val IrFunction.isOverridableOrOverrides
get() = this is IrSimpleFunction && (this.isOverridable || this.overriddenSymbols.isNotEmpty())
val IrClass.isFinalClass: Boolean
get() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS
fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean { fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean {
if (this == other) return true if (this == other) return true
@@ -152,10 +68,6 @@ fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean {
return false return false
} }
fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing()
internal val IrValueParameter.isValueParameter get() = this.index >= 0
private val IrCall.annotationClass private val IrCall.annotationClass
get() = (this.symbol.owner as IrConstructor).constructedClass get() = (this.symbol.owner as IrConstructor).constructedClass
@@ -169,31 +81,6 @@ fun List<IrCall>.findAnnotation(fqName: FqName): IrCall? = this.firstOrNull {
it.annotationClass.fqNameSafe == fqName it.annotationClass.fqNameSafe == fqName
} }
fun <T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? {
val annotation = this.annotations.findAnnotation(fqName)
if (annotation == null) {
// As a last resort try searching the descriptor.
// This is needed for a period while we don't have IR for platform libraries.
return this.descriptor.annotations
.findAnnotation(fqName)
?.getArgumentValueOrNull<T>(argumentName)
}
for (index in 0 until annotation.valueArgumentsCount) {
val parameter = annotation.symbol.owner.valueParameters[index]
if (parameter.name == Name.identifier(argumentName)) {
val actual = annotation.getValueArgument(index) as? IrConst<T>
return actual?.value
}
}
return null
}
fun IrValueParameter.isInlineParameter(): Boolean =
!this.isNoinline && (this.type.isFunction() || this.type.isSuspendFunction()) && !this.type.isMarkedNullable()
val IrDeclaration.parentDeclarationsWithSelf: Sequence<IrDeclaration>
get() = generateSequence(this, { it.parent as? IrDeclaration })
fun IrClass.companionObject() = this.declarations.singleOrNull {it is IrClass && it.isCompanion } fun IrClass.companionObject() = this.declarations.singleOrNull {it is IrClass && it.isCompanion }
val IrDeclaration.isGetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.getter val IrDeclaration.isGetter get() = this is IrSimpleFunction && this == this.correspondingProperty?.getter
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -30,10 +29,6 @@ internal val IrDeclaration.isLocal get() = DescriptorUtils.isLocal(this.descript
internal val IrDeclaration.module get() = this.descriptor.module internal val IrDeclaration.module get() = this.descriptor.module
@Deprecated("Do not call this method in the compiler front-end.")
internal val IrField.isDelegate
get() = @Suppress("DEPRECATION") this.descriptor.isDelegated
internal const val SYNTHETIC_OFFSET = -2 internal const val SYNTHETIC_OFFSET = -2
val File.lineStartOffsets: IntArray val File.lineStartOffsets: IntArray
@@ -211,31 +211,6 @@ private fun Name.mangleIfInternal(moduleDescriptor: ModuleDescriptor, visibility
"$this\$$moduleName" "$this\$$moduleName"
} }
internal val IrFunction.symbolName: String
get() {
if (!this.isExported()) {
throw AssertionError(this.descriptor.toString())
}
if (isExternal) {
this.descriptor.externalSymbolOrThrow()?.let {
return it
}
}
// this.descriptor.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let {
// val name = getAnnotationValue(it) ?: this.name.asString()
// return name // no wrapping currently required
// }
val parent = this.parent
val containingDeclarationPart = parent.fqNameSafe.let {
if (it.isRoot) "" else "$it."
}
return "kfun:$containingDeclarationPart$functionName"
}
internal val IrField.symbolName: String internal val IrField.symbolName: String
get() { get() {
val containingDeclarationPart = parent.fqNameSafe.let { val containingDeclarationPart = parent.fqNameSafe.let {
@@ -5,19 +5,11 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.descriptors.getFunction
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
import java.util.regex.Pattern
class DescriptorTable { class DescriptorTable {
private val descriptors = mutableMapOf<DeclarationDescriptor, Long>() private val descriptors = mutableMapOf<DeclarationDescriptor, Long>()
@@ -5,27 +5,9 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.typeUtil.isUnit
/**
* List of all implemented interfaces (including those which implemented by a super class)
*/
internal val IrClass.implementedInterfaces: List<IrClass>
get() {
val superClassImplementedInterfaces = this.getSuperClassNotAny()?.implementedInterfaces ?: emptyList()
val superInterfaces = this.getSuperInterfaces()
val superInterfacesImplementedInterfaces = superInterfaces.flatMap { it.implementedInterfaces }
return (superClassImplementedInterfaces +
superInterfacesImplementedInterfaces +
superInterfaces).distinct()
}
/** /**
@@ -71,62 +53,9 @@ internal fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false
return realSupers.first { allowAbstract || it.modality != Modality.ABSTRACT } return realSupers.first { allowAbstract || it.modality != Modality.ABSTRACT }
} }
// TODO: don't forget to remove descriptor access here.
//internal val FunctionDescriptor.isTypedIntrinsic: Boolean
// get() = this.descriptor.isTypedIntrinsic
//
//internal val DeclarationDescriptor.isFrozen: Boolean
// get() = this.descriptor.isFrozen
internal val arrayTypes = setOf(
"kotlin.Array",
"kotlin.ByteArray",
"kotlin.CharArray",
"kotlin.ShortArray",
"kotlin.IntArray",
"kotlin.LongArray",
"kotlin.FloatArray",
"kotlin.DoubleArray",
"kotlin.BooleanArray",
"kotlin.native.ImmutableBlob",
"kotlin.native.internal.NativePtrArray"
)
internal val IrClass.isArray: Boolean
get() = this.fqNameSafe.asString() in arrayTypes
internal val IrClass.isInterface: Boolean internal val IrClass.isInterface: Boolean
get() = (this.kind == ClassKind.INTERFACE) get() = (this.kind == ClassKind.INTERFACE)
fun IrClass.isAbstract() = this.modality == Modality.SEALED || this.modality == Modality.ABSTRACT
|| this.kind == ClassKind.ENUM_CLASS
//internal fun FunctionDescriptor.hasValueTypeAt(index: Int): Boolean {
// when (index) {
// 0 -> return !isSuspend && returnType.let { (it.isInlined() || it.isUnit()) }
// 1 -> return dispatchReceiverParameter.let { it != null && it.type.isInlined() }
// 2 -> return extensionReceiverParameter.let { it != null && it.type.isInlined() }
// else -> return this.valueParameters[index - 3].type.isInlined()
// }
//}
//
//internal fun FunctionDescriptor.hasReferenceAt(index: Int): Boolean {
// when (index) {
// 0 -> return isSuspend || returnType.let { !it.isInlined() && !it.isUnit() }
// 1 -> return dispatchReceiverParameter.let { it != null && !it.type.isInlined() }
// 2 -> return extensionReceiverParameter.let { it != null && !it.type.isInlined() }
// else -> return !this.valueParameters[index - 3].type.isInlined()
// }
//}
//private fun FunctionDescriptor.needBridgeToAt(target: FunctionDescriptor, index: Int)
// = hasValueTypeAt(index) xor target.hasValueTypeAt(index)
//internal fun FunctionDescriptor.needBridgeTo(target: FunctionDescriptor)
// = (0..this.valueParameters.size + 2).any { needBridgeToAt(target, it) }
internal val IrSimpleFunction.target: IrSimpleFunction internal val IrSimpleFunction.target: IrSimpleFunction
get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original
@@ -136,55 +65,6 @@ internal val IrFunction.target: IrFunction get() = when (this) {
else -> error(this) else -> error(this)
} }
//private fun FunctionDescriptor.bridgeDirectionToAt(target: FunctionDescriptor, index: Int)
// = when {
// hasValueTypeAt(index) && target.hasReferenceAt(index) -> BridgeDirection.FROM_VALUE_TYPE
// hasReferenceAt(index) && target.hasValueTypeAt(index) -> BridgeDirection.TO_VALUE_TYPE
// else -> BridgeDirection.NOT_NEEDED
//}
val IrSimpleFunction.allOverriddenDescriptors: Set<IrSimpleFunction>
get() {
val result = mutableSetOf<IrSimpleFunction>()
fun traverse(function: IrSimpleFunction) {
if (function in result) return
result += function
function.overriddenSymbols.forEach { traverse(it.owner) }
}
traverse(this)
return result
}
//internal fun IrSimpleFunction.bridgeDirectionsTo(
// overriddenDescriptor: IrSimpleFunction
//): BridgeDirections {
// val ourDirections = BridgeDirections(this.valueParameters.size)
// for (index in ourDirections.array.indices)
// ourDirections.array[index] = this.bridgeDirectionToAt(overriddenDescriptor, index)
//
// val target = this.target
// if (!this.isReal && modality != Modality.ABSTRACT
// && target.overrides(overriddenDescriptor)
// && ourDirections == target.bridgeDirectionsTo(overriddenDescriptor)) {
// // Bridge is inherited from superclass.
// return BridgeDirections(this.valueParameters.size)
// }
//
// return ourDirections
//}
tailrec internal fun IrDeclaration.findPackage(): IrPackageFragment {
val parent = this.parent
return parent as? IrPackageFragment
?: (parent as IrDeclaration).findPackage()
}
fun IrFunction.isComparisonDescriptor(map: Map<SimpleType, IrSimpleFunction>): Boolean =
this in map.values
val IrDeclaration.isPropertyAccessor get() = val IrDeclaration.isPropertyAccessor get() =
this is IrSimpleFunction && this.correspondingProperty != null this is IrSimpleFunction && this.correspondingProperty != null
@@ -13,13 +13,16 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
class DescriptorReferenceDeserializer( abstract class DescriptorReferenceDeserializer(
val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>, val currentModule: ModuleDescriptor,
val checkerDesc: (DeclarationDescriptor) -> Long?, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>
val checkerID: (Long) -> Boolean,
val descriptorResolver: (FqName) -> DeclarationDescriptor
) { ) {
protected abstract fun resolveSpecialDescriptor(fqn: FqName): DeclarationDescriptor
protected abstract fun checkIfSpecialDescriptorId(id: Long): Boolean
protected abstract fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long?
private val cache = mutableMapOf<String, Collection<DeclarationDescriptor>>() private val cache = mutableMapOf<String, Collection<DeclarationDescriptor>>()
private fun getContributedDescriptors(packageFqNameString: String): Collection<DeclarationDescriptor> = private fun getContributedDescriptors(packageFqNameString: String): Collection<DeclarationDescriptor> =
@@ -40,7 +43,7 @@ class DescriptorReferenceDeserializer(
private val membersCache = mutableMapOf<ClassName, ClassMembers>() private val membersCache = mutableMapOf<ClassName, ClassMembers>()
private fun computeUniqIdIndex(descriptor: DeclarationDescriptor) = descriptor.getUniqId()?.index ?: checkerDesc(descriptor) private fun computeUniqIdIndex(descriptor: DeclarationDescriptor) = descriptor.getUniqId()?.index ?: getDescriptorIdOrNull(descriptor)
private fun getMembers(packageFqNameString: String, classFqNameString: String, private fun getMembers(packageFqNameString: String, classFqNameString: String,
members: Collection<DeclarationDescriptor>): ClassMembers = members: Collection<DeclarationDescriptor>): ClassMembers =
@@ -119,8 +122,8 @@ class DescriptorReferenceDeserializer(
.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single() .getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
} }
if (protoIndex?.let { checkerID(it) } == true) { if (protoIndex?.let { checkIfSpecialDescriptorId(it) } == true) {
return descriptorResolver(packageFqName.child(Name.identifier(name))) return resolveSpecialDescriptor(packageFqName.child(Name.identifier(name)))
} }
val membersWithIndices = getMembers(packageFqNameString, classFqNameString, members) val membersWithIndices = getMembers(packageFqNameString, classFqNameString, members)
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataSerializerProtocol import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.JsKlibMetadataSerializerProtocol
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.* import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -31,36 +30,43 @@ class IrKlibProtoBufModuleDeserializer(
logger: LoggingContext, logger: LoggingContext,
builtIns: IrBuiltIns, builtIns: IrBuiltIns,
symbolTable: SymbolTable, symbolTable: SymbolTable,
val forwardModuleDescriptor: ModuleDescriptor?) private val forwardModuleDescriptor: ModuleDescriptor?)
: IrModuleDeserializer(logger, builtIns, symbolTable) { : IrModuleDeserializer(logger, builtIns, symbolTable) {
val deserializedSymbols = mutableMapOf<UniqIdKey, IrSymbol>() private val deserializedSymbols = mutableMapOf<UniqIdKey, IrSymbol>()
val knownBuiltInsDescriptors = mutableMapOf<DeclarationDescriptor, UniqId>() val knownBuiltInsDescriptors = mutableMapOf<DeclarationDescriptor, UniqId>()
val reachableTopLevels = mutableSetOf<UniqIdKey>() private val reachableTopLevels = mutableSetOf<UniqIdKey>()
val deserializedTopLevels = mutableSetOf<UniqIdKey>() private val deserializedTopLevels = mutableSetOf<UniqIdKey>()
val forwardDeclarations = mutableSetOf<IrSymbol>() private val forwardDeclarations = mutableSetOf<IrSymbol>()
var deserializedModuleDescriptor: ModuleDescriptor? = null private var deserializedModuleDescriptor: ModuleDescriptor? = null
var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrSymbolTable>() private var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrSymbolTable>()
var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.StringTable>() private var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.StringTable>()
var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrTypeTable>() private var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, IrKlibProtoBuf.IrTypeTable>()
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>() val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>()
val descriptorReferenceDeserializer = DescriptorReferenceDeserializer(currentModule, resolvedForwardDeclarations, {
knownBuiltInsDescriptors[it]?.index ?: if (isBuiltInFunction(it)) FUNCTION_INDEX_START + builtInFunctionId(it) else null
}, { (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_CLASS_OFFSET) <= it && it < (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_GAP) }, {
builtIns.builtIns.getBuiltInClassByFqName(it)
})
val descriptorToDirectoryMap = mutableMapOf<ModuleDescriptor, File>() private val descriptorReferenceDeserializer = object : DescriptorReferenceDeserializer(currentModule, resolvedForwardDeclarations) {
override fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn)
override fun checkIfSpecialDescriptorId(id: Long) =
(FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_CLASS_OFFSET) <= id && id < (FUNCTION_INDEX_START + BUILT_IN_UNIQ_ID_GAP)
override fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor) =
knownBuiltInsDescriptors[descriptor]?.index ?: if (isBuiltInFunction(descriptor))
FUNCTION_INDEX_START + builtInFunctionId(descriptor)
else null
}
private val descriptorToDirectoryMap = mutableMapOf<ModuleDescriptor, File>()
// val moduleRoot = libraryDir
private fun irDirectory(m: ModuleDescriptor): File = descriptorToDirectoryMap[m]!! private fun irDirectory(m: ModuleDescriptor): File = descriptorToDirectoryMap[m]!!
private val FUNCTION_INDEX_START: Long private val FUNCTION_INDEX_START: Long
init { init {
// TODO: think about order
var currentIndex = 0x1_0000_0000L var currentIndex = 0x1_0000_0000L
builtIns.knownBuiltins.forEach { builtIns.knownBuiltins.forEach {
require(it is IrFunction) require(it is IrFunction)
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ClassKind.* import org.jetbrains.kotlin.descriptors.ClassKind.*
@@ -15,11 +14,7 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.SourceManager import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.SourceRangeInfo
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
@@ -27,8 +22,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrNullaryPrimitiveImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrUnaryPrimitiveImpl import org.jetbrains.kotlin.ir.expressions.impl.IrUnaryPrimitiveImpl
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.js.resolve.JsPlatform.builtIns
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
internal class IrModuleSerializer( internal class IrModuleSerializer(
@@ -1,53 +0,0 @@
/*
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.StringTableImpl
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import java.io.OutputStream
class KonanStringTable : StringTableImpl() {
fun getClassOrPackageFqNameIndex(descriptor: ClassOrPackageFragmentDescriptor): Int {
when (descriptor) {
is PackageFragmentDescriptor ->
return getPackageFqNameIndex(descriptor.fqName)
is ClassDescriptor ->
return getFqNameIndex(descriptor as ClassifierDescriptorWithTypeParameters)
else -> error("Can not get fqNameIndex for $descriptor")
}
}
override fun getLocalClassIdReplacement(descriptor: ClassifierDescriptorWithTypeParameters): ClassId? {
return if (descriptor.containingDeclaration is CallableMemberDescriptor) {
val superClassifiers = descriptor.getAllSuperClassifiers()
.mapNotNull { it as ClassifierDescriptorWithTypeParameters }
.filter { it != descriptor }
.toList()
if (superClassifiers.size == 1) {
superClassifiers[0].classId
} else {
val superClass = superClassifiers.find { !DescriptorUtils.isInterface(it) }
superClass?.classId ?: ClassId.topLevel(descriptor.module.builtIns.any.fqNameSafe)
}
} else {
super.getLocalClassIdReplacement(descriptor)
}
}
fun serializeTo(output: OutputStream) {
val (strings, qualifiedNames) = buildProto()
strings.writeDelimitedTo(output)
qualifiedNames.writeDelimitedTo(output)
}
}
@@ -5,14 +5,12 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.backend.common.descriptors.propertyIfAccessor import org.jetbrains.kotlin.backend.common.descriptors.propertyIfAccessor
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
internal val DeclarationDescriptor.isExpectMember: Boolean internal val DeclarationDescriptor.isExpectMember: Boolean
get() = this is MemberDescriptor && this.isExpect get() = this is MemberDescriptor && this.isExpect
@@ -20,30 +18,6 @@ internal val DeclarationDescriptor.isExpectMember: Boolean
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this) get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this)
fun <T> AnnotationDescriptor.getArgumentValueOrNull(name: String): T? {
val constantValue = this.allValueArguments.entries.atMostOne {
it.key.asString() == name
}?.value
return constantValue?.value as T?
}
private val symbolNameAnnotation = FqName("kotlin.native.SymbolName")
fun getAnnotationValue(annotation: AnnotationDescriptor): String? {
return annotation.allValueArguments.values.ifNotEmpty {
val stringValue = single() as? StringValue
stringValue?.value
}
}
fun CallableMemberDescriptor.externalSymbolOrThrow(): String? {
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
return getAnnotationValue(it)!!
}
throw Error("external function ${this} must have @TypedIntrinsic, @SymbolName or @ObjCMethod annotation")
}
tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor { tailrec internal fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor {
return if (this is PackageFragmentDescriptor) this return if (this is PackageFragmentDescriptor) this
else this.containingDeclaration!!.findPackage() else this.containingDeclaration!!.findPackage()
@@ -1,35 +0,0 @@
/*
* Copyright 2010-2019 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.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf.QualifiedNameTable.QualifiedName
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.serialization.deserialization.getClassId
// TODO Come up with a better file name.
internal fun NameResolverImpl.getDescriptorByFqNameIndex(
module: ModuleDescriptor,
nameTable: ProtoBuf.QualifiedNameTable,
fqNameIndex: Int): DeclarationDescriptor {
if (fqNameIndex == -1) return module.getPackage(FqName.ROOT)
val packageName = this.getPackageFqName(fqNameIndex)
// TODO: Here we are using internals of NameresolverImpl.
// Consider extending NameResolver.
val proto = nameTable.getQualifiedName(fqNameIndex)
when (proto.kind!!) {
QualifiedName.Kind.CLASS,
QualifiedName.Kind.LOCAL ->
return module.findClassAcrossModuleDependencies(this.getClassId(fqNameIndex))!!
QualifiedName.Kind.PACKAGE ->
return module.getPackage(FqName(packageName))
}
}
@@ -22,11 +22,15 @@ data class UniqId (
// isLocal=true in UniqId is good while we dealing with a single current module. // isLocal=true in UniqId is good while we dealing with a single current module.
// To disambiguate module local declarations of different modules we use UniqIdKey. // To disambiguate module local declarations of different modules we use UniqIdKey.
// It has moduleDescriptor specified for isLocal=true uniqIds. // It has moduleDescriptor specified for isLocal=true uniqIds.
// TODO: make sure UniqId is really uniq for any global declaration
data class UniqIdKey private constructor(val uniqId: UniqId, val moduleDescriptor: ModuleDescriptor?) { data class UniqIdKey private constructor(val uniqId: UniqId, val moduleDescriptor: ModuleDescriptor?) {
constructor(moduleDescriptor: ModuleDescriptor?, uniqId: UniqId) constructor(moduleDescriptor: ModuleDescriptor?, uniqId: UniqId)
: this(uniqId, if (uniqId.isLocal) moduleDescriptor!! else null) : this(uniqId, if (uniqId.isLocal) moduleDescriptor!! else null)
} }
// TODO: think about this
internal val IrDeclaration.uniqIdIndex: Long internal val IrDeclaration.uniqIdIndex: Long
get() = this.uniqSymbolName().hashCode().toLong() get() = this.uniqSymbolName().hashCode().toLong()