[IR, JS] Refactoring: Introduce JsUnlinkedDeclarationsSupport
^KT-50775
This commit is contained in:
+7
-6
@@ -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())
|
||||
|
||||
+19
-17
@@ -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")
|
||||
}
|
||||
|
||||
+25
@@ -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
-7
@@ -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)
|
||||
|
||||
+23
@@ -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
|
||||
}
|
||||
+2
-2
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user