From 608885d1188b71cc8b4d5992d4e6a3f1e768f28d Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Tue, 29 Oct 2019 11:56:07 +0700 Subject: [PATCH] [Linker] Extend KotlinIrLinker infrastructure to support libraries that doesn't contain IR. Also bump ABI version because of addition of `ir_provider` property --- .../kotlin/ir/util/DeclarationStubGenerator.kt | 3 ++- .../src/org/jetbrains/kotlin/ir/util/SymbolTable.kt | 11 +++++++++++ .../backend/common/serialization/DeclarationTable.kt | 6 +++++- .../backend/common/serialization/KotlinIrLinker.kt | 9 +++++++++ .../common/serialization/LegacyDescriptorUtils.kt | 2 +- .../kotlin/ir/backend/js/JsLibraryResolver.kt | 3 ++- .../org/jetbrains/kotlin/library/KotlinAbiVersion.kt | 2 +- .../jetbrains/kotlin/library/SearchPathResolver.kt | 11 ++++++++++- 8 files changed, 41 insertions(+), 6 deletions(-) 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 94bab3ae08f..fdf01d918fa 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 @@ -49,7 +49,7 @@ class DeclarationStubGenerator( } - private val typeTranslator = TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true) + val typeTranslator = TypeTranslator(lazyTable, languageVersionSettings, moduleDescriptor.builtIns, LazyScopedTypeParametersResolver(lazyTable), true) private val constantValueGenerator = ConstantValueGenerator(moduleDescriptor, lazyTable) private val facadeClassMap = mutableMapOf() @@ -57,6 +57,7 @@ class DeclarationStubGenerator( init { typeTranslator.constantValueGenerator = constantValueGenerator constantValueGenerator.typeTranslator = typeTranslator + irProviders.filterIsInstance().forEach { it.declarationStubGenerator = this } } private fun getDeclaration(symbol: IrSymbol): IrDeclaration? { 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 afbabb0e8a5..808f1b66042 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 @@ -21,6 +21,7 @@ package org.jetbrains.kotlin.ir.util import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.* +import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase import org.jetbrains.kotlin.ir.declarations.lazy.IrLazySymbolTable import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpressionBody @@ -33,6 +34,16 @@ interface IrProvider { fun getDeclaration(symbol: IrSymbol): IrDeclaration? } +/** + * Extension of [IrProvider] which always produces inheritors of [IrLazyDeclarationBase]. + * Thus, it needs [declarationStubGenerator] to be able to produce IR declarations. + */ +interface LazyIrProvider: IrProvider { + var declarationStubGenerator: DeclarationStubGenerator + + override fun getDeclaration(symbol: IrSymbol): IrLazyDeclarationBase? +} + interface IrDeserializer : IrProvider { fun declareForwardDeclarations() } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt index 46f254db482..32f50f7d50a 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeclarationTable.kt @@ -56,7 +56,7 @@ abstract class GlobalDeclarationTable(private val mangler: KotlinMangler, privat fun isExportedDeclaration(declaration: IrDeclaration): Boolean = with(mangler) { declaration.isExported() } } -class DeclarationTable( +open class DeclarationTable( private val descriptorTable: DescriptorTable, private val globalDeclarationTable: GlobalDeclarationTable, startIndex: Long @@ -71,7 +71,11 @@ class DeclarationTable( fun isExportedDeclaration(declaration: IrDeclaration) = globalDeclarationTable.isExportedDeclaration(declaration) + protected open fun tryComputeBackendSpecificUniqId(declaration: IrDeclaration): UniqId? = + null + private fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId { + tryComputeBackendSpecificUniqId(declaration)?.let { return it } return if (declaration.isLocalDeclaration()) { table.getOrPut(declaration) { UniqId(localIndex++) } } else globalDeclarationTable.computeUniqIdByDeclaration(declaration) 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 ae24d8f4145..b0c397ecf59 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 @@ -506,6 +506,12 @@ abstract class KotlinIrLinker( error("Deserializer for declaration $key is not found") } + /** + * Check that descriptor shouldn't be processed by some backend-specific logic. + * For example, it is the case for Native interop libraries where there is no IR in libraries. + */ + protected open fun DeclarationDescriptor.shouldBeDeserialized(): Boolean = true + private fun deserializeAllReachableTopLevels() { do { val moduleDeserializer = modulesWithReachableTopLevels.first() @@ -521,6 +527,9 @@ abstract class KotlinIrLinker( // This is Native specific. Try to eliminate. if (topLevelDescriptor.module.isForwardDeclarationModule) return null + // + if (!topLevelDescriptor.shouldBeDeserialized()) return null + require(checkAccessibility(topLevelDescriptor)) { "Locally accessible declarations should not be accessed here $topLevelDescriptor" } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/LegacyDescriptorUtils.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/LegacyDescriptorUtils.kt index 6a1d6750527..b85a15ba16d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/LegacyDescriptorUtils.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/LegacyDescriptorUtils.kt @@ -21,7 +21,7 @@ internal val DeclarationDescriptor.isExpectMember: Boolean internal val DeclarationDescriptor.isSerializableExpectClass: Boolean get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this) -internal tailrec fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor { +tailrec fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor { return if (this is PackageFragmentDescriptor) this else this.containingDeclaration!!.findPackage() } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/JsLibraryResolver.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/JsLibraryResolver.kt index a1ac2a42646..133da7a6e97 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/JsLibraryResolver.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/JsLibraryResolver.kt @@ -33,7 +33,8 @@ class JsLibraryResolver( distributionKlib, localKotlinDir, skipCurrentDir, - logger + logger, + emptyList() ) { // Stick with the default KotlinLibrary for now. override fun libraryBuilder(file: File, isDefault: Boolean) = createKotlinLibrary(file, isDefault) diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt index 49cc5bc01dc..9b9e5aa21b9 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinAbiVersion.kt @@ -22,7 +22,7 @@ fun String.parseKonanAbiVersion(): KotlinAbiVersion { data class KotlinAbiVersion(val version: Int) { companion object { - val CURRENT = KotlinAbiVersion(18) + val CURRENT = KotlinAbiVersion(19) } override fun toString() = "$version" } diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt index 960d1f45ceb..da06b1f77c2 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt @@ -2,6 +2,7 @@ package org.jetbrains.kotlin.library import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.file.File +import org.jetbrains.kotlin.konan.properties.hasProperty import org.jetbrains.kotlin.library.impl.createKotlinLibrary import org.jetbrains.kotlin.util.* @@ -170,7 +171,8 @@ abstract class KotlinLibraryProperResolverWithAttributes( distributionKlib: String?, localKotlinDir: String?, skipCurrentDir: Boolean, - override val logger: Logger + override val logger: Logger, + private val knownIrProviders: List ) : KotlinLibrarySearchPathResolver(repositories, directLibs, distributionKlib, localKotlinDir, skipCurrentDir, logger), SearchPathResolverWithAttributes { @@ -209,6 +211,13 @@ abstract class KotlinLibraryProperResolverWithAttributes( return false } + candidate.manifestProperties["ir_provider"]?.let { + if (it !in knownIrProviders) { + logger.warning("skipping $candidatePath. The library requires unknown IR provider $it.") + return false + } + } + return true } } \ No newline at end of file