[Linker] Extend KotlinIrLinker infrastructure to support libraries that

doesn't contain IR. Also bump ABI version because of addition of `ir_provider` property
This commit is contained in:
Sergey Bogolepov
2019-10-29 11:56:07 +07:00
parent 5629627cca
commit 608885d118
8 changed files with 41 additions and 6 deletions
@@ -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 constantValueGenerator = ConstantValueGenerator(moduleDescriptor, lazyTable)
private val facadeClassMap = mutableMapOf<DeserializedContainerSource, IrClass?>() private val facadeClassMap = mutableMapOf<DeserializedContainerSource, IrClass?>()
@@ -57,6 +57,7 @@ class DeclarationStubGenerator(
init { init {
typeTranslator.constantValueGenerator = constantValueGenerator typeTranslator.constantValueGenerator = constantValueGenerator
constantValueGenerator.typeTranslator = typeTranslator constantValueGenerator.typeTranslator = typeTranslator
irProviders.filterIsInstance<LazyIrProvider>().forEach { it.declarationStubGenerator = this }
} }
private fun getDeclaration(symbol: IrSymbol): IrDeclaration? { private fun getDeclaration(symbol: IrSymbol): IrDeclaration? {
@@ -21,6 +21,7 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.* 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.declarations.lazy.IrLazySymbolTable
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
@@ -33,6 +34,16 @@ interface IrProvider {
fun getDeclaration(symbol: IrSymbol): IrDeclaration? 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 { interface IrDeserializer : IrProvider {
fun declareForwardDeclarations() fun declareForwardDeclarations()
} }
@@ -56,7 +56,7 @@ abstract class GlobalDeclarationTable(private val mangler: KotlinMangler, privat
fun isExportedDeclaration(declaration: IrDeclaration): Boolean = with(mangler) { declaration.isExported() } fun isExportedDeclaration(declaration: IrDeclaration): Boolean = with(mangler) { declaration.isExported() }
} }
class DeclarationTable( open class DeclarationTable(
private val descriptorTable: DescriptorTable, private val descriptorTable: DescriptorTable,
private val globalDeclarationTable: GlobalDeclarationTable, private val globalDeclarationTable: GlobalDeclarationTable,
startIndex: Long startIndex: Long
@@ -71,7 +71,11 @@ class DeclarationTable(
fun isExportedDeclaration(declaration: IrDeclaration) = globalDeclarationTable.isExportedDeclaration(declaration) fun isExportedDeclaration(declaration: IrDeclaration) = globalDeclarationTable.isExportedDeclaration(declaration)
protected open fun tryComputeBackendSpecificUniqId(declaration: IrDeclaration): UniqId? =
null
private fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId { private fun computeUniqIdByDeclaration(declaration: IrDeclaration): UniqId {
tryComputeBackendSpecificUniqId(declaration)?.let { return it }
return if (declaration.isLocalDeclaration()) { return if (declaration.isLocalDeclaration()) {
table.getOrPut(declaration) { UniqId(localIndex++) } table.getOrPut(declaration) { UniqId(localIndex++) }
} else globalDeclarationTable.computeUniqIdByDeclaration(declaration) } else globalDeclarationTable.computeUniqIdByDeclaration(declaration)
@@ -506,6 +506,12 @@ abstract class KotlinIrLinker(
error("Deserializer for declaration $key is not found") 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() { private fun deserializeAllReachableTopLevels() {
do { do {
val moduleDeserializer = modulesWithReachableTopLevels.first() val moduleDeserializer = modulesWithReachableTopLevels.first()
@@ -521,6 +527,9 @@ abstract class KotlinIrLinker(
// This is Native specific. Try to eliminate. // This is Native specific. Try to eliminate.
if (topLevelDescriptor.module.isForwardDeclarationModule) return null if (topLevelDescriptor.module.isForwardDeclarationModule) return null
//
if (!topLevelDescriptor.shouldBeDeserialized()) return null
require(checkAccessibility(topLevelDescriptor)) { require(checkAccessibility(topLevelDescriptor)) {
"Locally accessible declarations should not be accessed here $topLevelDescriptor" "Locally accessible declarations should not be accessed here $topLevelDescriptor"
} }
@@ -21,7 +21,7 @@ internal val DeclarationDescriptor.isExpectMember: Boolean
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this) get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this)
internal tailrec fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor { tailrec fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor {
return if (this is PackageFragmentDescriptor) this return if (this is PackageFragmentDescriptor) this
else this.containingDeclaration!!.findPackage() else this.containingDeclaration!!.findPackage()
} }
@@ -33,7 +33,8 @@ class JsLibraryResolver(
distributionKlib, distributionKlib,
localKotlinDir, localKotlinDir,
skipCurrentDir, skipCurrentDir,
logger logger,
emptyList()
) { ) {
// Stick with the default KotlinLibrary for now. // Stick with the default KotlinLibrary for now.
override fun libraryBuilder(file: File, isDefault: Boolean) = createKotlinLibrary(file, isDefault) override fun libraryBuilder(file: File, isDefault: Boolean) = createKotlinLibrary(file, isDefault)
@@ -22,7 +22,7 @@ fun String.parseKonanAbiVersion(): KotlinAbiVersion {
data class KotlinAbiVersion(val version: Int) { data class KotlinAbiVersion(val version: Int) {
companion object { companion object {
val CURRENT = KotlinAbiVersion(18) val CURRENT = KotlinAbiVersion(19)
} }
override fun toString() = "$version" override fun toString() = "$version"
} }
@@ -2,6 +2,7 @@ package org.jetbrains.kotlin.library
import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.File 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.library.impl.createKotlinLibrary
import org.jetbrains.kotlin.util.* import org.jetbrains.kotlin.util.*
@@ -170,7 +171,8 @@ abstract class KotlinLibraryProperResolverWithAttributes<L: KotlinLibrary>(
distributionKlib: String?, distributionKlib: String?,
localKotlinDir: String?, localKotlinDir: String?,
skipCurrentDir: Boolean, skipCurrentDir: Boolean,
override val logger: Logger override val logger: Logger,
private val knownIrProviders: List<String>
) : KotlinLibrarySearchPathResolver<L>(repositories, directLibs, distributionKlib, localKotlinDir, skipCurrentDir, logger), ) : KotlinLibrarySearchPathResolver<L>(repositories, directLibs, distributionKlib, localKotlinDir, skipCurrentDir, logger),
SearchPathResolverWithAttributes<L> SearchPathResolverWithAttributes<L>
{ {
@@ -209,6 +211,13 @@ abstract class KotlinLibraryProperResolverWithAttributes<L: KotlinLibrary>(
return false 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 return true
} }
} }