From 319125607e5011cef9ffc2ec29edd006d79196e8 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Thu, 13 Jan 2022 17:26:17 +0300 Subject: [PATCH] [IR, JS] Refactoring: Introduce JsUnlinkedDeclarationsSupport ^KT-50775 --- .../common/serialization/KotlinIrLinker.kt | 13 ++--- .../unlinked/UnlinkedDeclarationsProcessor.kt | 36 +++++++------- .../unlinked/UnlinkedDeclarationsSupport.kt | 25 ++++++++++ .../jetbrains/kotlin/ir/backend/js/klib.kt | 49 +++++++++---------- .../js/lower/serialization/ir/JsIrLinker.kt | 14 +++--- .../ir/JsUnlinkedDeclarationsSupport.kt | 23 +++++++++ .../konan/serialization/KonanIrlinker.kt | 4 +- 7 files changed, 106 insertions(+), 58 deletions(-) create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsSupport.kt create mode 100644 compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsUnlinkedDeclarationsSupport.kt 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 eee005ca315..c32cf2feaff 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 @@ -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, - 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 + 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 { - if (!allowUnboundSymbols) return emptySet() + if (!unlinkedDeclarationsSupport.allowUnboundSymbols) return emptySet() val entries = fakeOverrideBuilder.fakeOverrideCandidates val result = mutableSetOf() @@ -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()) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt index c42e2583c97..b760901ebe8 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsProcessor.kt @@ -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, + 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") } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsSupport.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsSupport.kt new file mode 100644 index 00000000000..b81facc801e --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/unlinked/UnlinkedDeclarationsSupport.kt @@ -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 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 whenUnboundSymbolsAllowed(action: (UnlinkedMarkerTypeHandler) -> T): T? = null + } + } +} 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 3e1abbcfa00..960641db6d7 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 @@ -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 = 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 a28eae4b431..35bb15b827f 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 @@ -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> = 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) diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsUnlinkedDeclarationsSupport.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsUnlinkedDeclarationsSupport.kt new file mode 100644 index 00000000000..9449160a3e9 --- /dev/null +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsUnlinkedDeclarationsSupport.kt @@ -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 whenUnboundSymbolsAllowed(action: (UnlinkedMarkerTypeHandler) -> T): T? = + if (allowUnboundSymbols) action(handler) else null +} diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt index ec4a501079c..4e8765f3f39 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt @@ -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")