[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
}
}
}
@@ -31,10 +31,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
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.JsManglerDesc
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.*
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
@@ -364,18 +361,18 @@ fun getIrModuleInfoForKlib(
val irBuiltIns = IrBuiltInsOverDescriptors(moduleDescriptor.builtIns, typeTranslator, symbolTable)
val allowUnboundSymbols = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
val unlinkedDeclarationsSupport = JsUnlinkedDeclarationsSupport(allowUnboundSymbols)
val irLinker =
JsIrLinker(
null,
messageLogger,
irBuiltIns,
symbolTable,
null,
null,
friendModules,
allowUnboundSymbols
)
val irLinker = JsIrLinker(
currentModule = null,
messageLogger = messageLogger,
builtIns = irBuiltIns,
symbolTable = symbolTable,
translationPluginContext = null,
icData = null,
friendModules = friendModules,
unlinkedDeclarationsSupport = unlinkedDeclarationsSupport
)
val deserializedModuleFragmentsToLib = deserializeDependencies(sortedDependencies, irLinker, mainModuleLib, filesToLoad, mapping)
val deserializedModuleFragments = deserializedModuleFragmentsToLib.keys.toList()
@@ -416,18 +413,18 @@ fun getIrModuleInfoForSourceFiles(
}
val allowUnboundSymbols = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
val unlinkedDeclarationsSupport = JsUnlinkedDeclarationsSupport(allowUnboundSymbols)
val irLinker =
JsIrLinker(
psi2IrContext.moduleDescriptor,
messageLogger,
irBuiltIns,
symbolTable,
feContext,
null,
friendModules,
allowUnboundSymbols
)
val irLinker = JsIrLinker(
currentModule = psi2IrContext.moduleDescriptor,
messageLogger = messageLogger,
builtIns = irBuiltIns,
symbolTable = symbolTable,
translationPluginContext = feContext,
icData = null,
friendModules = friendModules,
unlinkedDeclarationsSupport = unlinkedDeclarationsSupport
)
val deserializedModuleFragmentsToLib = deserializeDependencies(allSortedDependencies, irLinker, null,null, mapping)
val deserializedModuleFragments = deserializedModuleFragmentsToLib.keys.toList()
(irBuiltIns as IrBuiltInsOverDescriptors).functionFactory =
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsSupport
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
@@ -23,14 +24,13 @@ class JsIrLinker(
override val translationPluginContext: TranslationPluginContext?,
private val icData: ICData? = null,
friendModules: Map<String, Collection<String>> = emptyMap(),
allowUnboundSymbols: Boolean = false
override val unlinkedDeclarationsSupport: UnlinkedDeclarationsSupport = JsUnlinkedDeclarationsSupport(allowUnboundSymbols = false)
) : KotlinIrLinker(
currentModule,
messageLogger,
builtIns,
symbolTable,
emptyList(),
allowUnboundSymbols,
currentModule = currentModule,
messageLogger = messageLogger,
builtIns = builtIns,
symbolTable = symbolTable,
exportedDependencies = emptyList(),
symbolProcessor = { symbol, idSig ->
if (idSig.isLocal) {
symbol.privateSignature = IdSignature.CompositeSignature(IdSignature.FileSignature(fileSymbol), idSig)
@@ -0,0 +1,23 @@
/*
* 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.ir.backend.js.lower.serialization.ir
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsSupport
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsSupport.UnlinkedMarkerTypeHandler
import org.jetbrains.kotlin.ir.types.IrErrorType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
import org.jetbrains.kotlin.types.Variance
class JsUnlinkedDeclarationsSupport(override val allowUnboundSymbols: Boolean) : UnlinkedDeclarationsSupport {
private val handler = object : UnlinkedMarkerTypeHandler {
override val unlinkedMarkerType = IrErrorTypeImpl(null, emptyList(), Variance.INVARIANT)
override fun IrType.isUnlinkedMarkerType() = this is IrErrorType
}
override fun <T : Any> whenUnboundSymbolsAllowed(action: (UnlinkedMarkerTypeHandler) -> T): T? =
if (allowUnboundSymbols) action(handler) else null
}
@@ -322,8 +322,8 @@ internal class KonanIrLinker(
private val cachedLibraries: CachedLibraries,
private val lazyIrForCaches: Boolean,
override val userVisibleIrModulesSupport: UserVisibleIrModulesSupport,
allowUnboundSymbols: Boolean
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, exportedDependencies, allowUnboundSymbols) {
allowUnboundSymbols: Boolean // TODO
) : KotlinIrLinker(currentModule, messageLogger, builtIns, symbolTable, exportedDependencies) {
companion object {
private val C_NAMES_NAME = Name.identifier("cnames")