[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
@@ -221,8 +221,8 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, private val
val intAnd = getBinaryOperator(OperatorNameConventions.AND, builtIns.intType, builtIns.intType)
val intPlusInt = getBinaryOperator(OperatorNameConventions.PLUS, builtIns.intType, builtIns.intType)
fun functionN(n: Int): IrClassSymbol = symbolTable.referenceClass(builtIns.getFunction(n))
fun suspendFunctionN(n: Int): IrClassSymbol = symbolTable.referenceClass(builtIns.getSuspendFunction(n))
open fun functionN(n: Int): IrClassSymbol = symbolTable.referenceClass(builtIns.getFunction(n))
open fun suspendFunctionN(n: Int): IrClassSymbol = symbolTable.referenceClass(builtIns.getSuspendFunction(n))
val extensionToString = getSimpleFunction(Name.identifier("toString")) {
it.dispatchReceiverParameter == null && it.extensionReceiverParameter != null &&
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.IrDeserializer
import org.jetbrains.kotlin.ir.util.IrProvider
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -71,17 +72,18 @@ class Psi2IrTranslator(
fun generateModuleFragment(
context: GeneratorContext,
ktFiles: Collection<KtFile>,
deserializer: IrDeserializer? = null
deserializer: IrDeserializer? = null,
irProviders: List<IrProvider> = emptyList()
): IrModuleFragment {
val moduleGenerator = ModuleGenerator(context)
val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles)
// This is required for implicit casts insertion on IrTypes (work-in-progress).
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, facadeClassGenerator)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, facadeClassGenerator)
irModule.patchDeclarationParents()
postprocess(context, irModule)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, facadeClassGenerator)
moduleGenerator.generateUnboundSymbolsAsDependencies(irModule, deserializer, irProviders, facadeClassGenerator)
return irModule
}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.ir.util.IrDeserializer
import org.jetbrains.kotlin.ir.util.IrProvider
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile
@@ -48,6 +49,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
fun generateUnboundSymbolsAsDependencies(
irModule: IrModuleFragment,
deserializer: IrDeserializer? = null,
irProviders: List<IrProvider> = emptyList(),
facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
) {
ExternalDependenciesGenerator(
@@ -56,6 +58,7 @@ class ModuleGenerator(override val context: GeneratorContext) : Generator {
context.irBuiltIns,
context.extensions.externalDeclarationOrigin,
deserializer,
irProviders,
facadeClassGenerator
).generateUnboundSymbolsAsDependencies()
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.declarations.lazy.*
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
@@ -36,7 +37,7 @@ class DeclarationStubGenerator(
val symbolTable: SymbolTable,
languageVersionSettings: LanguageVersionSettings,
private val externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = null,
private val deserializer: IrDeserializer? = null,
private val irProviders: List<IrProvider> = emptyList(),
private val facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
) {
private val lazyTable = symbolTable.lazyWrapper
@@ -58,6 +59,12 @@ class DeclarationStubGenerator(
constantValueGenerator.typeTranslator = typeTranslator
}
private fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
for (irProvider in irProviders)
irProvider.getDeclaration(symbol)?.let { return it }
return null
}
fun generateOrGetEmptyExternalPackageFragmentStub(descriptor: PackageFragmentDescriptor): IrExternalPackageFragment {
val referenced = symbolTable.referenceExternalPackageFragment(descriptor)
if (referenced.isBound) {
@@ -114,7 +121,7 @@ class DeclarationStubGenerator(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original,
isDelegated = @Suppress("DEPRECATION") descriptor.isDelegated
) {
deserializer?.findDeserializedDeclaration(referenced) as? IrProperty
getDeclaration(referenced) as? IrProperty
?: IrLazyProperty(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator, bindingContext)
}
}
@@ -131,7 +138,7 @@ class DeclarationStubGenerator(
else computeOrigin(descriptor)
return symbolTable.declareField(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original, descriptor.type.toIrType()) {
deserializer?.findDeserializedDeclaration(referenced) as? IrField
getDeclaration(referenced) as? IrField
?: IrLazyField(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
@@ -158,7 +165,7 @@ class DeclarationStubGenerator(
origin,
descriptor.original
) {
deserializer?.findDeserializedDeclaration(referenced) as? IrSimpleFunction
getDeclaration(referenced) as? IrSimpleFunction
?: IrLazyFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
@@ -173,7 +180,7 @@ class DeclarationStubGenerator(
return symbolTable.declareConstructor(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor.original
) {
deserializer?.findDeserializedDeclaration(referenced) as? IrConstructor
getDeclaration(referenced) as? IrConstructor
?: IrLazyConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
@@ -204,7 +211,7 @@ class DeclarationStubGenerator(
}
val origin = computeOrigin(descriptor)
return symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
deserializer?.findDeserializedDeclaration(referenceClass) as? IrClass
getDeclaration(referenceClass) as? IrClass
?: IrLazyClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
@@ -216,7 +223,7 @@ class DeclarationStubGenerator(
}
val origin = computeOrigin(descriptor)
return symbolTable.declareEnumEntry(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
deserializer?.findDeserializedDeclaration(referenced) as? IrEnumEntry
getDeclaration(referenced) as? IrEnumEntry
?: IrLazyEnumEntryImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
@@ -228,7 +235,7 @@ class DeclarationStubGenerator(
}
val origin = computeOrigin(descriptor)
return symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, descriptor) {
deserializer?.findDeserializedDeclaration(referenced) as? IrTypeParameter
getDeclaration(referenced) as? IrTypeParameter
?: IrLazyTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, it, this, typeTranslator)
}
}
@@ -31,38 +31,45 @@ class ExternalDependenciesGenerator(
val irBuiltIns: IrBuiltIns,
externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = null,
private val deserializer: IrDeserializer? = null,
irProviders: List<IrProvider> = emptyList(),
facadeClassGenerator: (DeserializedContainerSource) -> IrClass? = { null }
) {
private val stubGenerator = DeclarationStubGenerator(
moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings, externalDeclarationOrigin, deserializer, facadeClassGenerator
moduleDescriptor, symbolTable, irBuiltIns.languageVersionSettings, externalDeclarationOrigin,
listOfNotNull(deserializer) + irProviders, facadeClassGenerator
)
fun generateUnboundSymbolsAsDependencies() {
stubGenerator.unboundSymbolGeneration = true
ArrayList(symbolTable.unboundClasses).forEach {
stubGenerator.generateClassStub(it.descriptor)
}
ArrayList(symbolTable.unboundConstructors).forEach {
stubGenerator.generateConstructorStub(it.descriptor)
}
ArrayList(symbolTable.unboundEnumEntries).forEach {
stubGenerator.generateEnumEntryStub(it.descriptor)
}
ArrayList(symbolTable.unboundFields).forEach {
stubGenerator.generateFieldStub(it.descriptor)
}
ArrayList(symbolTable.unboundSimpleFunctions).forEach {
stubGenerator.generateFunctionStub(it.descriptor)
}
ArrayList(symbolTable.unboundProperties).forEach {
stubGenerator.generatePropertyStub(it.descriptor)
}
ArrayList(symbolTable.unboundTypeParameters).forEach {
stubGenerator.generateOrGetTypeParameterStub(it.descriptor)
}
ArrayList(symbolTable.unboundTypeAliases).forEach {
stubGenerator.generateTypeAliasStub(it.descriptor)
}
do {
fun <T> haveNotStabilized(prev: ArrayList<T>, cur: Set<T>) =
cur.isNotEmpty() && (prev.size != cur.size || prev.any { !cur.contains(it) })
val unboundClasses = ArrayList(symbolTable.unboundClasses)
val unboundConstructors = ArrayList(symbolTable.unboundConstructors)
val unboundEnumEntries = ArrayList(symbolTable.unboundEnumEntries)
val unboundFields = ArrayList(symbolTable.unboundFields)
val unboundSimpleFunctions = ArrayList(symbolTable.unboundSimpleFunctions)
val unboundProperties = ArrayList(symbolTable.unboundProperties)
val unboundTypeParameters = ArrayList(symbolTable.unboundTypeParameters)
val unboundTypeAliases = ArrayList(symbolTable.unboundTypeAliases)
unboundClasses.forEach { stubGenerator.generateClassStub(it.descriptor) }
unboundConstructors.forEach { stubGenerator.generateConstructorStub(it.descriptor) }
unboundEnumEntries.forEach { stubGenerator.generateEnumEntryStub(it.descriptor) }
unboundFields.forEach { stubGenerator.generateFieldStub(it.descriptor) }
unboundSimpleFunctions.forEach { stubGenerator.generateFunctionStub(it.descriptor) }
unboundProperties.forEach { stubGenerator.generatePropertyStub(it.descriptor) }
unboundTypeParameters.forEach { stubGenerator.generateOrGetTypeParameterStub(it.descriptor) }
unboundTypeAliases.forEach { stubGenerator.generateTypeAliasStub(it.descriptor) }
} while (haveNotStabilized(unboundClasses, symbolTable.unboundClasses)
|| haveNotStabilized(unboundConstructors, symbolTable.unboundConstructors)
|| haveNotStabilized(unboundEnumEntries, symbolTable.unboundEnumEntries)
|| haveNotStabilized(unboundFields, symbolTable.unboundFields)
|| haveNotStabilized(unboundSimpleFunctions, symbolTable.unboundSimpleFunctions)
|| haveNotStabilized(unboundProperties, symbolTable.unboundProperties)
|| haveNotStabilized(unboundTypeParameters, symbolTable.unboundTypeParameters)
|| haveNotStabilized(unboundTypeAliases, symbolTable.unboundTypeAliases)
)
deserializer?.declareForwardDeclarations()
@@ -29,8 +29,11 @@ import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
interface IrDeserializer {
fun findDeserializedDeclaration(symbol: IrSymbol): IrDeclaration?
interface IrProvider {
fun getDeclaration(symbol: IrSymbol): IrDeclaration?
}
interface IrDeserializer : IrProvider {
fun declareForwardDeclarations()
}
@@ -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()
}
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsDeclarationTable
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.newJsDescriptorUniqId
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.*
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.*
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -127,7 +124,7 @@ fun loadIr(
val symbolTable = psi2IrContext.symbolTable
val moduleDescriptor = psi2IrContext.moduleDescriptor
val deserializer = JsIrLinker(moduleDescriptor, emptyLoggingContext, irBuiltIns, symbolTable)
val deserializer = JsIrLinker(moduleDescriptor, JsMangler, emptyLoggingContext, irBuiltIns, symbolTable)
val deserializedModuleFragments = allDependencies.map {
deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!!
@@ -8,6 +8,7 @@ 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
@@ -8,24 +8,12 @@ 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.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.ir.util.nameForIrSerialization
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.findFirstFunction
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")))
internal const val PUBLIC_LOCAL_UNIQ_ID_EDGE = 0x7FFF_FFFF_FFFF_FFFFL + 1L
internal const val BUILT_IN_FUNCTION_CLASS_COUNT = 4
@@ -33,16 +21,6 @@ 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
internal fun isBuiltInFunction(value: IrDeclaration): Boolean = when (value) {
is IrSimpleFunction ->
value.name.asString() == "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
}
private fun builtInOffset(function: IrSimpleFunction): Long {
val isK = function.parentAsClass.name.asString().startsWith("K")
return when {
@@ -63,16 +41,6 @@ internal fun builtInFunctionId(value: IrDeclaration): Long = when (value) {
else -> error("Only class or function is expected")
}
internal 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
}
private fun builtInOffset(function: FunctionInvokeDescriptor): Long {
val isK = function.containingDeclaration.name.asString().startsWith("K")
return when {
@@ -5,9 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.serialization.DescriptorReferenceDeserializer
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
import org.jetbrains.kotlin.backend.common.serialization.UniqIdKey
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
@@ -16,9 +14,10 @@ import org.jetbrains.kotlin.name.FqName
class JsDescriptorReferenceDeserializer(
currentModule: ModuleDescriptor,
mangler: KotlinMangler,
val builtIns: IrBuiltIns,
val FUNCTION_INDEX_START: Long) :
DescriptorReferenceDeserializer(currentModule, mutableMapOf<UniqIdKey, UniqIdKey>()),
DescriptorReferenceDeserializer(currentModule, mangler, mutableMapOf<UniqIdKey, UniqIdKey>()),
DescriptorUniqIdAware by JsDescriptorUniqIdAware {
override fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn)
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
class JsIrLinker(
currentModule: ModuleDescriptor,
mangler: KotlinMangler,
logger: LoggingContext,
builtIns: IrBuiltIns,
symbolTable: SymbolTable
@@ -28,7 +29,7 @@ class JsIrLinker(
builtIns.getPrimitiveTypeOrNullByDescriptor(symbol.descriptor, hasQuestionMark)
override val descriptorReferenceDeserializer =
JsDescriptorReferenceDeserializer(currentModule, builtIns, FUNCTION_INDEX_START)
JsDescriptorReferenceDeserializer(currentModule, mangler, builtIns, FUNCTION_INDEX_START)
override fun reader(moduleDescriptor: ModuleDescriptor, uniqId: UniqId): ByteArray {
return moduleDescriptor.kotlinLibrary.irDeclaration(uniqId.index, uniqId.isLocal)
@@ -50,9 +50,13 @@ class FunctionInterfaceMemberScope(
TODO()
}
private val classifiers = mutableMapOf<Name, ClassifierDescriptor>()
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = when {
classDescriptorFactory.shouldCreateClass(packageName, name) ->
classDescriptorFactory.createClass(ClassId.topLevel(packageName.child(name)))
classifiers.getOrPut(name) {
classDescriptorFactory.createClass(ClassId.topLevel(packageName.child(name)))!!
}
else -> null
}
}