diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt index c81ed1348d2..40fa364e825 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt @@ -221,8 +221,8 @@ abstract class Symbols(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 && diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt index 28c8048e12d..0c7a1d17396 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -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, - deserializer: IrDeserializer? = null + deserializer: IrDeserializer? = null, + irProviders: List = 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 } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt index 6234c0a1f4f..207b19c1301 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt @@ -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 = 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() } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt index 7fa82da3324..94bab3ae08f 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeclarationStubGenerator.kt @@ -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 = 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) } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt index eb2ebdc1295..84b27553d8a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/ExternalDependenciesGenerator.kt @@ -31,38 +31,45 @@ class ExternalDependenciesGenerator( val irBuiltIns: IrBuiltIns, externalDeclarationOrigin: ((DeclarationDescriptor) -> IrDeclarationOrigin)? = null, private val deserializer: IrDeserializer? = null, + irProviders: List = 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 haveNotStabilized(prev: ArrayList, cur: Set) = + 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() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt index ec83035f647..626e8209136 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt @@ -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() } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt index 58dbc699834..c7765210dbc 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope abstract class DescriptorReferenceDeserializer( val currentModule: ModuleDescriptor, + val mangler: KotlinMangler, val resolvedForwardDeclarations: MutableMap ) : DescriptorUniqIdAware { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/FunctionalInterfacesUtils.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/FunctionalInterfacesUtils.kt new file mode 100644 index 00000000000..99a85664c75 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/FunctionalInterfacesUtils.kt @@ -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 +} diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt index 1ff09f92dd1..5f2a9fc1a80 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrModuleSerializer.kt @@ -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)) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index a4300b01200..5e8bfa89deb 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -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 diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt index b8edb5e757e..be01e962520 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt @@ -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 = "" + 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 . 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() } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 3dae9b95f48..8dc56d328a2 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -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))!! diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt index d387a7e528e..999fb5a6a5c 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTable.kt @@ -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 diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt index b1f00657d53..916f52de1f4 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDeclarationTableUtils.kt @@ -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 { diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt index 5c56b077070..66975716bd6 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsDescriptorReferenceDeserializer.kt @@ -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()), + DescriptorReferenceDeserializer(currentModule, mangler, mutableMapOf()), DescriptorUniqIdAware by JsDescriptorUniqIdAware { override fun resolveSpecialDescriptor(fqn: FqName) = builtIns.builtIns.getBuiltInClassByFqName(fqn) diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index e533de7c59e..8571db1c0d1 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -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) diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInterfaceFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInterfaceFactory.kt index 7780d082551..d45c57fbdb4 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInterfaceFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/functions/FunctionInterfaceFactory.kt @@ -50,9 +50,13 @@ class FunctionInterfaceMemberScope( TODO() } + private val classifiers = mutableMapOf() + 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 } }