[IrSerializer] Preparations for functional interfaces handling

This commit is contained in:
Igor Chevdar
2019-08-02 14:08:38 +03:00
parent c007f3efb3
commit 00dc335559
17 changed files with 145 additions and 91 deletions
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
abstract class DescriptorReferenceDeserializer(
val currentModule: ModuleDescriptor,
val mangler: KotlinMangler,
val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>
) : DescriptorUniqIdAware {
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.backend.common.serialization
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
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.fqNameWhenAvailable
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.regex.Pattern
private val functionPattern = Pattern.compile("^K?(Suspend)?Function\\d+$")
private val kotlinFqn = FqName("kotlin")
private val functionalPackages =
listOf(kotlinFqn, kotlinFqn.child(Name.identifier("coroutines")), kotlinFqn.child(Name.identifier("reflect")))
fun isBuiltInFunction(value: IrDeclaration): Boolean = when (value) {
is IrSimpleFunction ->
value.name == OperatorNameConventions.INVOKE && (value.parent as? IrClass)?.let { isBuiltInFunction(it) } == true
is IrClass ->
value.fqNameWhenAvailable?.parent() in functionalPackages &&
value.name.asString().let { functionPattern.matcher(it).find() }
else -> false
}
fun isBuiltInFunction(value: DeclarationDescriptor): Boolean = when (value) {
is FunctionInvokeDescriptor -> isBuiltInFunction(value.containingDeclaration)
is ClassDescriptor -> {
val fqn = (value.containingDeclaration as? PackageFragmentDescriptor)?.fqName
functionalPackages.any { it == fqn } && value.name.asString().let { functionPattern.matcher(it).find() }
}
else -> false
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.common.serialization
import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.builtins.FunctionInterfacePackageFragment
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ClassKind.*
import org.jetbrains.kotlin.descriptors.Modality
@@ -1306,11 +1307,12 @@ open class IrModuleSerializer(
val proto = ProtoModule.newBuilder()
.setName(serializeName(module.name))
val topLevelDeclarationsCount = module.files.sumBy { it.declarations.size }
val files = module.files.filter { it.packageFragmentDescriptor !is FunctionInterfacePackageFragment }
val topLevelDeclarationsCount = files.sumBy { it.declarations.size }
writer = CombinedIrFileWriter(topLevelDeclarationsCount)
module.files.forEach {
files.forEach {
proto.addFile(serializeIrFile(it))
}
@@ -414,7 +414,7 @@ abstract class KotlinIrLinker(
return topLevelDescriptor
}
override fun findDeserializedDeclaration(symbol: IrSymbol): IrDeclaration? {
override fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
if (!symbol.isBound) {
findDeserializedDeclarationForDescriptor(symbol.descriptor) ?: return null
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.backend.common.serialization
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.*
@@ -22,6 +19,13 @@ interface KotlinMangler {
fun IrDeclaration.isExported(): Boolean
val IrFunction.functionName: String
val IrType.isInlined: Boolean
val Long.isSpecial: Boolean
companion object {
private val FUNCTION_PREFIX = "<BUILT-IN-FUNCTION>"
fun functionClassSymbolName(name: Name) = "ktype:$FUNCTION_PREFIX$name"
fun functionInvokeSymbolName(name: Name) = "kfun:$FUNCTION_PREFIX$name.invoke"
}
}
abstract class KotlinManglerImpl : KotlinMangler {
@@ -177,6 +181,9 @@ abstract class KotlinManglerImpl : KotlinMangler {
return "$name$signature"
}
override val Long.isSpecial: Boolean
get() = specialHashes.contains(this)
fun Name.mangleIfInternal(moduleDescriptor: ModuleDescriptor, visibility: Visibility): String =
if (visibility != Visibilities.INTERNAL) {
this.asString()
@@ -199,6 +206,8 @@ abstract class KotlinManglerImpl : KotlinMangler {
val IrClass.typeInfoSymbolName: String
get() {
assert(this.isExported())
if (isBuiltInFunction(this))
return KotlinMangler.functionClassSymbolName(name)
return "ktype:" + this.fqNameForIrSerialization.toString()
}
@@ -270,6 +279,8 @@ abstract class KotlinManglerImpl : KotlinMangler {
// In addition functions appearing in fq sequence appear as <full signature>.
private val IrFunction.uniqFunctionName: String
get() {
if (isBuiltInFunction(this))
return KotlinMangler.functionInvokeSymbolName(parentAsClass.name)
val parent = this.parent
val containingDeclarationPart = parent.fqNameUnique.let {
@@ -279,5 +290,9 @@ abstract class KotlinManglerImpl : KotlinMangler {
return "kfun:$containingDeclarationPart#$functionName"
}
private val specialHashes = listOf("Function", "KFunction", "SuspendFunction", "KSuspendFunction")
.flatMap { name ->
(0..255).map { KotlinMangler.functionClassSymbolName(Name.identifier(name + it)) }
}.map { it.hashMangle }
.toSet()
}