[IrSerializer] Removed hacks with functional interfaces

This commit is contained in:
Igor Chevdar
2019-08-05 13:49:09 +03:00
parent 00dc335559
commit 226013353d
5 changed files with 27 additions and 103 deletions
@@ -5,11 +5,11 @@
package org.jetbrains.kotlin.backend.common.serialization
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -17,16 +17,30 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.resolve.scopes.MemberScope
// This is all information needed to find a descriptor in the
// tree of deserialized descriptors. Think of it as base + offset.
// packageFqName + classFqName + index allow to localize some deserialized descriptor.
// Then the rest of the fields allow to find the needed descriptor relative to the one with index.
abstract class DescriptorReferenceDeserializer(
val currentModule: ModuleDescriptor,
val mangler: KotlinMangler,
val builtIns: IrBuiltIns,
val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>
) : DescriptorUniqIdAware {
protected open fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn)
protected abstract fun resolveSpecialDescriptor(fqn: FqName): DeclarationDescriptor
protected abstract fun checkIfSpecialDescriptorId(id: Long): Boolean
protected abstract fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long?
protected open fun checkIfSpecialDescriptorId(id: Long) = with(mangler) { id.isSpecial }
protected open fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor) =
if (isBuiltInFunction(descriptor)) {
val uniqName = when (descriptor) {
is FunctionClassDescriptor -> KotlinMangler.functionClassSymbolName(descriptor.name)
is FunctionInvokeDescriptor -> KotlinMangler.functionInvokeSymbolName(descriptor.containingDeclaration.name)
else -> error("Unexpected descriptor type: $descriptor")
}
with(mangler) { uniqName.hashMangle }
} else null
protected fun getContributedDescriptors(packageFqNameString: String, name: String): Collection<DeclarationDescriptor> {
val packageFqName = packageFqNameString.let {
@@ -5,24 +5,15 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.serialization.UniqId
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.backend.common.serialization.isBuiltInFunction
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
class JsDeclarationTable(builtIns: IrBuiltIns, descriptorTable: DescriptorTable) : DeclarationTable(builtIns, descriptorTable, JsMangler) {
override var currentIndex = PUBLIC_LOCAL_UNIQ_ID_EDGE
private val FUNCTION_INDEX_START: Long = loadKnownBuiltins()
init {
currentIndex += BUILT_IN_UNIQ_ID_GAP
loadKnownBuiltins()
}
override fun computeUniqIdByDeclaration(value: IrDeclaration) =
if (isBuiltInFunction(value)) {
UniqId(FUNCTION_INDEX_START + builtInFunctionId(value), false)
} else super.computeUniqIdByDeclaration(value)
}
@@ -5,58 +5,4 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.psi2ir.findFirstFunction
internal const val PUBLIC_LOCAL_UNIQ_ID_EDGE = 0x7FFF_FFFF_FFFF_FFFFL + 1L
internal const val BUILT_IN_FUNCTION_CLASS_COUNT = 4
internal const val BUILT_IN_FUNCTION_ARITY_COUNT = 256
internal const val BUILT_IN_UNIQ_ID_GAP = 2 * BUILT_IN_FUNCTION_ARITY_COUNT * BUILT_IN_FUNCTION_CLASS_COUNT
internal const val BUILT_IN_UNIQ_ID_CLASS_OFFSET = BUILT_IN_FUNCTION_CLASS_COUNT * BUILT_IN_FUNCTION_ARITY_COUNT
private fun builtInOffset(function: IrSimpleFunction): Long {
val isK = function.parentAsClass.name.asString().startsWith("K")
return when {
isK && function.isSuspend -> 3
isK -> 2
function.isSuspend -> 1
else -> 0
}
}
internal fun builtInFunctionId(value: IrDeclaration): Long = when (value) {
is IrSimpleFunction -> {
value.run { valueParameters.size + builtInOffset(value) * BUILT_IN_FUNCTION_ARITY_COUNT }.toLong()
}
is IrClass -> {
BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.declarations.first { it.nameForIrSerialization.asString() == "invoke" })
}
else -> error("Only class or function is expected")
}
private fun builtInOffset(function: FunctionInvokeDescriptor): Long {
val isK = function.containingDeclaration.name.asString().startsWith("K")
return when {
isK && function.isSuspend -> 3
isK -> 2
function.isSuspend -> 1
else -> 0
}
}
internal fun builtInFunctionId(value: DeclarationDescriptor): Long = when (value) {
is FunctionInvokeDescriptor -> {
value.run { valueParameters.size + builtInOffset(value) * BUILT_IN_FUNCTION_ARITY_COUNT }.toLong()
}
is ClassDescriptor -> {
BUILT_IN_UNIQ_ID_CLASS_OFFSET + builtInFunctionId(value.findFirstFunction("invoke") { true })
}
else -> error("Only class or function is expected")
}
@@ -6,28 +6,16 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.name.FqName
class JsDescriptorReferenceDeserializer(
currentModule: ModuleDescriptor,
mangler: KotlinMangler,
val builtIns: IrBuiltIns,
val FUNCTION_INDEX_START: Long) :
DescriptorReferenceDeserializer(currentModule, mangler, mutableMapOf<UniqIdKey, UniqIdKey>()),
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
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) =
if (isBuiltInFunction(descriptor))
FUNCTION_INDEX_START + builtInFunctionId(descriptor)
else null
}
builtIns: IrBuiltIns
) : DescriptorReferenceDeserializer(currentModule, mangler, builtIns, mutableMapOf()),
DescriptorUniqIdAware by JsDescriptorUniqIdAware
@@ -23,13 +23,11 @@ class JsIrLinker(
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, PUBLIC_LOCAL_UNIQ_ID_EDGE),
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
private val FUNCTION_INDEX_START: Long = indexAfterKnownBuiltins
override fun getPrimitiveTypeOrNull(symbol: IrClassifierSymbol, hasQuestionMark: Boolean) =
builtIns.getPrimitiveTypeOrNullByDescriptor(symbol.descriptor, hasQuestionMark)
override val descriptorReferenceDeserializer =
JsDescriptorReferenceDeserializer(currentModule, mangler, builtIns, FUNCTION_INDEX_START)
JsDescriptorReferenceDeserializer(currentModule, mangler, builtIns)
override fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray {
return moduleDescriptor.kotlinLibrary.irDeclaration(uniqId.index, uniqId.isLocal)
@@ -56,17 +54,4 @@ class JsIrLinker(
}
private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath
override fun declareForwardDeclarations() {
// since for `knownBuiltIns` such as FunctionN it is possible to have unbound symbols after deserialization
// reference them through out lazy symbol table
with(symbolTable) {
ArrayList(unboundClasses).forEach { lazyWrapper.referenceClass(it.descriptor) }
ArrayList(unboundConstructors).forEach { lazyWrapper.referenceConstructor(it.descriptor) }
ArrayList(unboundEnumEntries).forEach { lazyWrapper.referenceEnumEntry(it.descriptor) }
ArrayList(unboundFields).forEach { lazyWrapper.referenceField(it.descriptor) }
ArrayList(unboundSimpleFunctions).forEach { lazyWrapper.referenceSimpleFunction(it.descriptor) }
ArrayList(unboundTypeParameters).forEach { lazyWrapper.referenceTypeParameter(it.descriptor) }
}
}
}