[IR, JS] Refactoring: Introduce JsUnlinkedDeclarationsSupport

^KT-50775
This commit is contained in:
Dmitriy Dolovov
2022-01-13 17:26:17 +03:00
parent 0b1a7d05a9
commit 319125607e
7 changed files with 106 additions and 58 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.overrides.FileLocalAwareLinker
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.backend.common.serialization.linkerissues.*
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsProcessor
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsSupport
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -37,7 +38,6 @@ abstract class KotlinIrLinker(
val builtIns: IrBuiltIns,
val symbolTable: SymbolTable,
private val exportedDependencies: List<ModuleDescriptor>,
private val allowUnboundSymbols: Boolean = false,
val symbolProcessor: IrSymbolDeserializer.(IrSymbol, IdSignature) -> IrSymbol = { s, _ -> s },
) : IrDeserializer, FileLocalAwareLinker {
@@ -59,13 +59,14 @@ abstract class KotlinIrLinker(
private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>
protected open val unlinkedDeclarationsSupport: UnlinkedDeclarationsSupport = UnlinkedDeclarationsSupport.DISABLED
protected open val userVisibleIrModulesSupport: UserVisibleIrModulesSupport = UserVisibleIrModulesSupport.DEFAULT
fun handleSignatureIdNotFoundInModuleWithDependencies(
idSignature: IdSignature,
moduleDeserializer: IrModuleDeserializer
): IrModuleDeserializer {
if (allowUnboundSymbols) {
if (unlinkedDeclarationsSupport.allowUnboundSymbols) {
return object : IrModuleDeserializer(null, KotlinAbiVersion.CURRENT) {
override fun contains(idSig: IdSignature): Boolean = false
@@ -169,7 +170,7 @@ abstract class KotlinIrLinker(
?: tryResolveCustomDeclaration(symbol)
?: return null
} catch (e: IrSymbolTypeMismatchException) {
if (!allowUnboundSymbols) {
if (!unlinkedDeclarationsSupport.allowUnboundSymbols) {
throw SymbolTypeMismatch(e, deserializersForModules.values, userVisibleIrModulesSupport).raiseIssue(messageLogger)
}
}
@@ -220,7 +221,7 @@ abstract class KotlinIrLinker(
private fun markUnlinkedClassifiers(): Set<IrClassifierSymbol> {
if (!allowUnboundSymbols) return emptySet()
if (!unlinkedDeclarationsSupport.allowUnboundSymbols) return emptySet()
val entries = fakeOverrideBuilder.fakeOverrideCandidates
val result = mutableSetOf<IrClassifierSymbol>()
@@ -299,8 +300,8 @@ abstract class KotlinIrLinker(
fakeOverrideBuilder.provideFakeOverrides()
triedToDeserializeDeclarationForSymbol.clear()
if (allowUnboundSymbols) {
val t = UnlinkedDeclarationsProcessor(builtIns, unlinkedClassifiers, messageLogger)
unlinkedDeclarationsSupport.whenUnboundSymbolsAllowed { unlinkedMarkerTypeHandler ->
val t = UnlinkedDeclarationsProcessor(builtIns, unlinkedClassifiers, unlinkedMarkerTypeHandler, messageLogger)
t.addLinkageErrorIntoUnlinkedClasses()
applyToModules(t.signatureTransformer())
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.common.serialization.unlinked
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsSupport.UnlinkedMarkerTypeHandler
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
@@ -15,21 +16,19 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.types.IrErrorType
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.ir.util.fileOrNull
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.types.Variance
internal class UnlinkedDeclarationsProcessor(
private val builtIns: IrBuiltIns,
private val unlinkedClassifiers: Set<IrClassifierSymbol>,
private val unlinkedMarkerTypeHandler: UnlinkedMarkerTypeHandler,
private val messageLogger: IrMessageLogger
) {
@@ -64,8 +63,6 @@ internal class UnlinkedDeclarationsProcessor(
}
}
private val errorType = IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT)
private fun IrDeclaration.location(): IrMessageLogger.Location? = fileOrNull?.location(startOffset)
private fun IrFile.location(offset: Int): IrMessageLogger.Location {
@@ -95,12 +92,12 @@ internal class UnlinkedDeclarationsProcessor(
fun IrValueParameter.fixType() {
if (type.isUnlinked()) {
linked = false
type = errorType
type = unlinkedMarkerTypeHandler.unlinkedMarkerType
defaultValue = null
}
varargElementType?.let {
if (it.isUnlinked()) {
varargElementType = errorType
varargElementType = unlinkedMarkerTypeHandler.unlinkedMarkerType
}
}
}
@@ -109,12 +106,12 @@ internal class UnlinkedDeclarationsProcessor(
declaration.valueParameters.forEach { it.fixType() }
if (declaration.returnType.isUnlinked()) {
linked = false
declaration.returnType = errorType
declaration.returnType = unlinkedMarkerTypeHandler.unlinkedMarkerType
}
declaration.typeParameters.forEach {
if (it.superTypes.any { s -> s.isUnlinked() }) {
linked = false
it.superTypes = listOf(errorType)
it.superTypes = listOf(unlinkedMarkerTypeHandler.unlinkedMarkerType)
}
}
if (linked) {
@@ -138,7 +135,7 @@ internal class UnlinkedDeclarationsProcessor(
val kind = if (declaration.correspondingPropertySymbol != null) "Property" else "Field"
declaration.reportWarning(kind, fqn.asString())
declaration.type = errorType
declaration.type = unlinkedMarkerTypeHandler.unlinkedMarkerType
declaration.initializer = null
} else {
declaration.transformChildrenVoid()
@@ -172,19 +169,24 @@ internal class UnlinkedDeclarationsProcessor(
}
private fun IrFieldSymbol.isUnlinked(): Boolean {
return owner.type is IrErrorType
return owner.type.isUnlinkedMarkerType()
}
private fun IrFunctionSymbol.isUnlinked(): Boolean {
val function = owner
if (function.returnType is IrErrorType) return true
if (function.dispatchReceiverParameter?.type is IrErrorType) return true
if (function.extensionReceiverParameter?.type is IrErrorType) return true
if (function.valueParameters.any { it.type is IrErrorType }) return true
if (function.typeParameters.any { tp -> tp.superTypes.any { st -> st is IrErrorType } }) return true
if (function.returnType.isUnlinkedMarkerType()) return true
if (function.dispatchReceiverParameter?.type?.isUnlinkedMarkerType() == true) return true
if (function.extensionReceiverParameter?.type?.isUnlinkedMarkerType() == true) return true
if (function.valueParameters.any { it.type.isUnlinkedMarkerType() }) return true
if (function.typeParameters.any { tp -> tp.superTypes.any { st -> st.isUnlinkedMarkerType() } }) return true
return false
}
// That's not the same as IrType.isUnlinked()!
private fun IrType.isUnlinkedMarkerType(): Boolean {
return with(unlinkedMarkerTypeHandler) { isUnlinkedMarkerType() }
}
private fun IrElement.throwLinkageError(message: String?): IrCall {
return IrCallImpl(startOffset, endOffset, builtIns.nothingType, builtIns.linkageErrorSymbol, 0, 1, errorOrigin).also { call ->
val messageLiteral = "Linkage error of symbol: ${message ?: ""}"
@@ -224,7 +226,7 @@ internal class UnlinkedDeclarationsProcessor(
}
override fun visitExpression(expression: IrExpression): IrExpression {
if (expression.type.isUnlinked() || expression.type is IrErrorType) {
if (expression.type.isUnlinked() || expression.type.isUnlinkedMarkerType()) {
reportWarning("Expression type contains unlinked symbol", currentFile?.location(expression.startOffset))
return expression.throwLinkageError("Unlinked type of expression")
}
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2022 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.unlinked
import org.jetbrains.kotlin.ir.types.IrType
interface UnlinkedDeclarationsSupport {
val allowUnboundSymbols: Boolean
fun <T : Any> whenUnboundSymbolsAllowed(action: (UnlinkedMarkerTypeHandler) -> T): T?
interface UnlinkedMarkerTypeHandler {
val unlinkedMarkerType: IrType
fun IrType.isUnlinkedMarkerType(): Boolean
}
companion object {
val DISABLED = object : UnlinkedDeclarationsSupport {
override val allowUnboundSymbols get() = false
override fun <T : Any> whenUnboundSymbolsAllowed(action: (UnlinkedMarkerTypeHandler) -> T): T? = null
}
}
}