[IR] Partial linkage fix: Implement abstract fake overrides in non-abstract classes so that there are no call sites that still refer to abstract fake overrides
^KT-53663
This commit is contained in:
+22
-8
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.overrides
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
@@ -17,18 +17,26 @@ import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
|
||||
// This is basicly modelled after the inliner copier.
|
||||
class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map<IrTypeParameterSymbol, IrType>) {
|
||||
|
||||
fun copy(irElement: IrElement, parent: IrClass): IrElement {
|
||||
// This is basically modelled after the inliner copier.
|
||||
class CopyIrTreeWithSymbolsForFakeOverrides(
|
||||
private val overridableMember: IrOverridableMember,
|
||||
typeArguments: Map<IrTypeParameterSymbol, IrType>,
|
||||
private val parent: IrClass,
|
||||
unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy
|
||||
) {
|
||||
fun copy(): IrOverridableMember {
|
||||
// Create new symbols.
|
||||
irElement.acceptVoid(symbolRemapper)
|
||||
overridableMember.acceptVoid(symbolRemapper)
|
||||
|
||||
// Make symbol remapper aware of the callsite's type arguments.
|
||||
// Copy IR.
|
||||
val result = irElement.transform(if (parent.isEffectivelyExternal()) copierMakingExternal else copier, data = null)
|
||||
val result = overridableMember.transform(
|
||||
if (parent.isEffectivelyExternal()) copierMakingExternal else copier,
|
||||
data = null
|
||||
) as IrOverridableMember
|
||||
|
||||
result.patchDeclarationParents(parent)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -82,10 +90,14 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map<IrTypeParamet
|
||||
typeArguments,
|
||||
NullDescriptorsRemapper
|
||||
)
|
||||
|
||||
private val copier = FakeOverrideCopier(
|
||||
symbolRemapper,
|
||||
FakeOverrideTypeRemapper(symbolRemapper, typeArguments),
|
||||
SymbolRenamer.DEFAULT
|
||||
SymbolRenamer.DEFAULT,
|
||||
makeExternal = false,
|
||||
parent,
|
||||
unimplementedOverridesStrategy
|
||||
)
|
||||
|
||||
private val copierMakingExternal = FakeOverrideCopier(
|
||||
@@ -93,5 +105,7 @@ class DeepCopyIrTreeWithSymbolsForFakeOverrides(typeArguments: Map<IrTypeParamet
|
||||
FakeOverrideTypeRemapper(symbolRemapper, typeArguments),
|
||||
SymbolRenamer.DEFAULT,
|
||||
makeExternal = true,
|
||||
parent,
|
||||
unimplementedOverridesStrategy
|
||||
)
|
||||
}
|
||||
@@ -12,48 +12,20 @@ class FakeOverrideCopier(
|
||||
private val symbolRemapper: SymbolRemapper,
|
||||
private val typeRemapper: TypeRemapper,
|
||||
private val symbolRenamer: SymbolRenamer,
|
||||
private val makeExternal: Boolean = false,
|
||||
private val makeExternal: Boolean,
|
||||
private val parent: IrClass,
|
||||
private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper, symbolRenamer) {
|
||||
|
||||
private fun <T : IrFunction> T.transformFunctionChildren(declaration: T): T =
|
||||
apply {
|
||||
transformAnnotations(declaration)
|
||||
copyTypeParametersFrom(declaration)
|
||||
typeRemapper.withinScope(this) {
|
||||
// This is the more correct way to produce dispatch receiver for a fake override,
|
||||
// but some lowerings still expect the below behavior as produced by the current psi2ir.
|
||||
/*
|
||||
val superDispatchReceiver = declaration.dispatchReceiverParameter!!
|
||||
val dispatchReceiverSymbol = IrValueParameterSymbolImpl(WrappedReceiverParameterDescriptor())
|
||||
val dispatchReceiverType = destinationClass.defaultType
|
||||
dispatchReceiverParameter = IrValueParameterImpl(
|
||||
superDispatchReceiver.startOffset,
|
||||
superDispatchReceiver.endOffset,
|
||||
superDispatchReceiver.origin,
|
||||
dispatchReceiverSymbol,
|
||||
superDispatchReceiver.name,
|
||||
superDispatchReceiver.index,
|
||||
dispatchReceiverType,
|
||||
null,
|
||||
superDispatchReceiver.isCrossinline,
|
||||
superDispatchReceiver.isNoinline
|
||||
)
|
||||
*/
|
||||
// Should fake override's receiver be the current class is an open question.
|
||||
dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform()
|
||||
extensionReceiverParameter = declaration.extensionReceiverParameter?.transform()
|
||||
returnType = typeRemapper.remapType(declaration.returnType)
|
||||
this.valueParameters = declaration.valueParameters.transform()
|
||||
}
|
||||
}
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction {
|
||||
val customization = unimplementedOverridesStrategy.computeCustomization(declaration, parent)
|
||||
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction =
|
||||
declaration.factory.createFunctionWithLateBinding(
|
||||
return declaration.factory.createFunctionWithLateBinding(
|
||||
declaration.startOffset, declaration.endOffset,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
customization.origin ?: IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
symbolRenamer.getFunctionName(declaration.symbol),
|
||||
declaration.visibility,
|
||||
declaration.modality,
|
||||
customization.modality ?: declaration.modality,
|
||||
declaration.returnType,
|
||||
isInline = declaration.isInline,
|
||||
isExternal = makeExternal,
|
||||
@@ -63,17 +35,50 @@ class FakeOverrideCopier(
|
||||
isOperator = declaration.isOperator,
|
||||
isInfix = declaration.isInfix
|
||||
).apply {
|
||||
transformFunctionChildren(declaration)
|
||||
transformAnnotations(declaration)
|
||||
copyTypeParametersFrom(declaration)
|
||||
typeRemapper.withinScope(this) {
|
||||
// This is the more correct way to produce dispatch receiver for a fake override,
|
||||
// but some lowerings still expect the below behavior as produced by the current psi2ir.
|
||||
/*
|
||||
val superDispatchReceiver = declaration.dispatchReceiverParameter!!
|
||||
val dispatchReceiverSymbol = IrValueParameterSymbolImpl(WrappedReceiverParameterDescriptor())
|
||||
val dispatchReceiverType = destinationClass.defaultType
|
||||
dispatchReceiverParameter = IrValueParameterImpl(
|
||||
superDispatchReceiver.startOffset,
|
||||
superDispatchReceiver.endOffset,
|
||||
superDispatchReceiver.origin,
|
||||
dispatchReceiverSymbol,
|
||||
superDispatchReceiver.name,
|
||||
superDispatchReceiver.index,
|
||||
dispatchReceiverType,
|
||||
null,
|
||||
superDispatchReceiver.isCrossinline,
|
||||
superDispatchReceiver.isNoinline
|
||||
)
|
||||
*/
|
||||
// Should fake override's receiver be the current class is an open question.
|
||||
dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform()
|
||||
extensionReceiverParameter = declaration.extensionReceiverParameter?.transform()
|
||||
returnType = typeRemapper.remapType(declaration.returnType)
|
||||
valueParameters = declaration.valueParameters.transform()
|
||||
|
||||
if (customization.needToCreateBody && body == null) {
|
||||
body = factory.createBlockBody(startOffset, endOffset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitProperty(declaration: IrProperty): IrProperty {
|
||||
val customization = unimplementedOverridesStrategy.computeCustomization(declaration, parent)
|
||||
|
||||
override fun visitProperty(declaration: IrProperty): IrProperty =
|
||||
declaration.factory.createPropertyWithLateBinding(
|
||||
return declaration.factory.createPropertyWithLateBinding(
|
||||
declaration.startOffset, declaration.endOffset,
|
||||
IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
customization.origin ?: IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
declaration.name,
|
||||
declaration.visibility,
|
||||
declaration.modality,
|
||||
customization.modality ?: declaration.modality,
|
||||
isVar = declaration.isVar,
|
||||
isConst = declaration.isConst,
|
||||
isLateinit = declaration.isLateinit,
|
||||
@@ -85,6 +90,7 @@ class FakeOverrideCopier(
|
||||
this.getter = declaration.getter?.transform()
|
||||
this.setter = declaration.setter?.transform()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitValueParameter(declaration: IrValueParameter): IrValueParameter =
|
||||
declaration.factory.createValueParameter(
|
||||
|
||||
@@ -17,10 +17,12 @@ import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
abstract class FakeOverrideBuilderStrategy(private val friendModules: Map<String, Collection<String>>) {
|
||||
|
||||
abstract class FakeOverrideBuilderStrategy(
|
||||
private val friendModules: Map<String, Collection<String>>,
|
||||
private val unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy
|
||||
) {
|
||||
open fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember =
|
||||
buildFakeOverrideMember(superType, member, clazz, friendModules)
|
||||
buildFakeOverrideMember(superType, member, clazz, friendModules, unimplementedOverridesStrategy)
|
||||
|
||||
fun linkFakeOverride(fakeOverride: IrOverridableMember, compatibilityMode: Boolean) {
|
||||
when (fakeOverride) {
|
||||
@@ -61,11 +63,13 @@ private fun isInFriendModules(
|
||||
return toModuleName in fromFriends
|
||||
}
|
||||
|
||||
fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember {
|
||||
return buildFakeOverrideMember(superType, member, clazz, emptyMap())
|
||||
}
|
||||
|
||||
fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass, friendModules: Map<String, Collection<String>>): IrOverridableMember {
|
||||
fun buildFakeOverrideMember(
|
||||
superType: IrType,
|
||||
member: IrOverridableMember,
|
||||
clazz: IrClass,
|
||||
friendModules: Map<String, Collection<String>> = emptyMap(),
|
||||
unimplementedOverridesStrategy: IrUnimplementedOverridesStrategy = IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides
|
||||
): IrOverridableMember {
|
||||
require(superType is IrSimpleType) { "superType is $superType, expected IrSimpleType" }
|
||||
val classifier = superType.classifier
|
||||
require(classifier is IrClassSymbol) { "superType classifier is not IrClassSymbol: $classifier" }
|
||||
@@ -86,13 +90,12 @@ fun buildFakeOverrideMember(superType: IrType, member: IrOverridableMember, claz
|
||||
substitutionMap[tp.symbol] = ta.type
|
||||
}
|
||||
|
||||
val copier = DeepCopyIrTreeWithSymbolsForFakeOverrides(substitutionMap)
|
||||
val deepCopyFakeOverride = copier.copy(member, clazz) as IrOverridableMember
|
||||
deepCopyFakeOverride.parent = clazz
|
||||
if (deepCopyFakeOverride.isPrivateToThisModule(clazz, classifier.owner, friendModules))
|
||||
deepCopyFakeOverride.visibility = DescriptorVisibilities.INVISIBLE_FAKE
|
||||
|
||||
return deepCopyFakeOverride
|
||||
return CopyIrTreeWithSymbolsForFakeOverrides(member, substitutionMap, clazz, unimplementedOverridesStrategy)
|
||||
.copy()
|
||||
.apply {
|
||||
if (isPrivateToThisModule(clazz, classifier.owner, friendModules))
|
||||
visibility = DescriptorVisibilities.INVISIBLE_FAKE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+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.ir.overrides
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
|
||||
|
||||
interface IrUnimplementedOverridesStrategy {
|
||||
class Customization(val origin: IrDeclarationOrigin?, val modality: Modality?, val needToCreateBody: Boolean) {
|
||||
companion object {
|
||||
val NO = Customization(null, null, false)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : IrOverridableMember> computeCustomization(overridableMember: T, parent: IrClass): Customization
|
||||
|
||||
object ProcessAsFakeOverrides : IrUnimplementedOverridesStrategy {
|
||||
override fun <T : IrOverridableMember> computeCustomization(overridableMember: T, parent: IrClass) = Customization.NO
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
|
||||
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
|
||||
import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy
|
||||
import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
@@ -24,7 +26,6 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
@@ -1101,8 +1102,10 @@ val IrFunction.allParametersCount: Int
|
||||
// This is essentially the same as FakeOverrideBuilder,
|
||||
// but it bypasses SymbolTable.
|
||||
// TODO: merge it with FakeOverrideBuilder.
|
||||
private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(emptyMap()) {
|
||||
|
||||
private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(
|
||||
friendModules = emptyMap(),
|
||||
unimplementedOverridesStrategy = ProcessAsFakeOverrides
|
||||
) {
|
||||
override fun linkFunctionFakeOverride(declaration: IrFunctionWithLateBinding, compatibilityMode: Boolean) {
|
||||
declaration.acquireSymbol(IrSimpleFunctionSymbolImpl())
|
||||
}
|
||||
|
||||
+25
-1
@@ -21,9 +21,14 @@ import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
|
||||
import org.jetbrains.kotlin.backend.common.serialization.GlobalDeclarationTable
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedDeclarationsProcessor.Companion.MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
|
||||
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
|
||||
import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy
|
||||
import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy.Customization
|
||||
import org.jetbrains.kotlin.ir.overrides.IrUnimplementedOverridesStrategy.ProcessAsFakeOverrides
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
|
||||
@@ -63,17 +68,36 @@ object DefaultFakeOverrideClassFilter : FakeOverrideClassFilter {
|
||||
override fun needToConstructFakeOverrides(clazz: IrClass): Boolean = true
|
||||
}
|
||||
|
||||
private object ImplementAsErrorThrowingStubs : IrUnimplementedOverridesStrategy {
|
||||
override fun <T : IrOverridableMember> computeCustomization(overridableMember: T, parent: IrClass) =
|
||||
if (overridableMember.modality == Modality.ABSTRACT
|
||||
&& parent.modality != Modality.ABSTRACT
|
||||
&& parent.modality != Modality.SEALED
|
||||
) {
|
||||
Customization(
|
||||
origin = MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION,
|
||||
modality = parent.modality, // Use modality of class for implemented callable member.
|
||||
needToCreateBody = true // At least it should have empty body. Later, the body will be patched in UnlinkedDeclarationsProcessor.
|
||||
)
|
||||
} else
|
||||
Customization.NO
|
||||
}
|
||||
|
||||
class FakeOverrideBuilder(
|
||||
val linker: FileLocalAwareLinker,
|
||||
val symbolTable: SymbolTable,
|
||||
mangler: KotlinMangler.IrMangler,
|
||||
typeSystem: IrTypeSystemContext,
|
||||
friendModules: Map<String, Collection<String>>,
|
||||
partialLinkageEnabled: Boolean,
|
||||
val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter,
|
||||
private val fakeOverrideDeclarationTable: DeclarationTable = FakeOverrideDeclarationTable(mangler) { builder, table ->
|
||||
IdSignatureSerializer(builder, table)
|
||||
}
|
||||
) : FakeOverrideBuilderStrategy(friendModules) {
|
||||
) : FakeOverrideBuilderStrategy(
|
||||
friendModules = friendModules,
|
||||
unimplementedOverridesStrategy = if (partialLinkageEnabled) ImplementAsErrorThrowingStubs else ProcessAsFakeOverrides
|
||||
) {
|
||||
private val haveFakeOverrides = mutableSetOf<IrClass>()
|
||||
|
||||
private val irOverridingUtil = IrOverridingUtil(typeSystem, this)
|
||||
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* 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.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
internal inline fun <reified T : IrOverridableDeclaration<*>> T.deepCopyWithImplementedFakeOverrides(): T {
|
||||
val clazz = parentAsClass
|
||||
|
||||
return deepCopyWithSymbols(clazz, DeepCopySymbolRemapperPreservingSignatures()) { symbolRemapper, typeRemapper ->
|
||||
ImplementedFakeOverrideCopier(clazz, symbolRemapper, typeRemapper)
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImplementedFakeOverrideCopier(
|
||||
private val clazz: IrClass,
|
||||
private val symbolRemapper: SymbolRemapper,
|
||||
private val typeRemapper: TypeRemapper
|
||||
) : DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
|
||||
override fun visitProperty(declaration: IrProperty): IrProperty =
|
||||
declaration.factory.createProperty(
|
||||
startOffset = declaration.startOffset,
|
||||
endOffset = declaration.endOffset,
|
||||
origin = MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION, // Customized.
|
||||
symbol = symbolRemapper.getDeclaredProperty(declaration.symbol),
|
||||
name = declaration.name,
|
||||
visibility = declaration.visibility,
|
||||
modality = clazz.modality, // Customized.
|
||||
isVar = declaration.isVar,
|
||||
isConst = declaration.isConst,
|
||||
isLateinit = declaration.isLateinit,
|
||||
isDelegated = declaration.isDelegated,
|
||||
isExternal = declaration.isExternal,
|
||||
isExpect = declaration.isExpect,
|
||||
isFakeOverride = false, // Customized.
|
||||
containerSource = declaration.containerSource,
|
||||
).apply {
|
||||
overriddenSymbols = declaration.overriddenSymbols.map { symbolRemapper.getReferencedProperty(it) }
|
||||
copyAttributes(declaration)
|
||||
transformAnnotations(declaration)
|
||||
backingField = declaration.backingField?.transform()?.also { it.correspondingPropertySymbol = symbol }
|
||||
getter = declaration.getter?.transform()?.also { it.correspondingPropertySymbol = symbol }
|
||||
setter = declaration.setter?.transform()?.also { it.correspondingPropertySymbol = symbol }
|
||||
}
|
||||
|
||||
override fun visitSimpleFunction(declaration: IrSimpleFunction): IrSimpleFunction =
|
||||
declaration.factory.createFunction(
|
||||
startOffset = declaration.startOffset,
|
||||
endOffset = declaration.endOffset,
|
||||
origin = MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION, // Customized.
|
||||
symbol = symbolRemapper.getDeclaredFunction(declaration.symbol),
|
||||
name = declaration.name,
|
||||
visibility = declaration.visibility,
|
||||
modality = clazz.modality, // Customized.
|
||||
returnType = declaration.returnType,
|
||||
isInline = declaration.isInline,
|
||||
isExternal = declaration.isExternal,
|
||||
isTailrec = declaration.isTailrec,
|
||||
isSuspend = declaration.isSuspend,
|
||||
isOperator = declaration.isOperator,
|
||||
isInfix = declaration.isInfix,
|
||||
isExpect = declaration.isExpect,
|
||||
isFakeOverride = false, // Customized.
|
||||
containerSource = declaration.containerSource,
|
||||
).apply {
|
||||
overriddenSymbols = declaration.overriddenSymbols.map { symbolRemapper.getReferencedFunction(it) as IrSimpleFunctionSymbol }
|
||||
contextReceiverParametersCount = declaration.contextReceiverParametersCount
|
||||
copyAttributes(declaration)
|
||||
transformAnnotations(this)
|
||||
copyTypeParametersFrom(declaration)
|
||||
typeRemapper.withinScope(this) {
|
||||
dispatchReceiverParameter = declaration.dispatchReceiverParameter?.transform()
|
||||
extensionReceiverParameter = declaration.extensionReceiverParameter?.transform()
|
||||
returnType = typeRemapper.remapType(declaration.returnType)
|
||||
valueParameters = declaration.valueParameters.transform()
|
||||
body = factory.createBlockBody(
|
||||
declaration.body?.startOffset ?: declaration.startOffset,
|
||||
declaration.body?.endOffset ?: declaration.endOffset
|
||||
) // the body should be empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION =
|
||||
object : IrDeclarationOriginImpl("MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION", isSynthetic = true) {}
|
||||
+6
-37
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.serialization.unlinked.PartialLinkage
|
||||
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedIrElementRenderer.appendDeclaration
|
||||
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UnlinkedIrElementRenderer.renderError
|
||||
import org.jetbrains.kotlin.backend.common.serialization.unlinked.UsedClassifierSymbolStatus.Companion.isUnlinked
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -60,31 +59,11 @@ internal class UnlinkedDeclarationsProcessor(
|
||||
fun signatureTransformer(): IrElementTransformerVoid = SignatureTransformer()
|
||||
|
||||
private inner class SignatureTransformer : IrElementTransformerVoid() {
|
||||
private val implementedFakeOverrideProperties = hashSetOf<IrProperty>()
|
||||
|
||||
private val IrFunction.isAccessorOfImplementedFakeOverrideProperty: Boolean
|
||||
get() = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner in implementedFakeOverrideProperties
|
||||
|
||||
override fun visitProperty(declaration: IrProperty): IrStatement {
|
||||
val newProperty = declaration.replaceIfUnimplementedFakeOverride()
|
||||
|
||||
val isImplementedFakeOverride = newProperty != declaration
|
||||
if (isImplementedFakeOverride) implementedFakeOverrideProperties += newProperty
|
||||
|
||||
newProperty.transformChildrenVoid()
|
||||
|
||||
if (isImplementedFakeOverride) implementedFakeOverrideProperties -= newProperty
|
||||
|
||||
return newProperty
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
val newFunction = declaration.replaceIfUnimplementedFakeOverride()
|
||||
val removedUnlinkedTypes = newFunction.fixUnlinkedTypes()
|
||||
val removedUnlinkedTypes = declaration.fixUnlinkedTypes()
|
||||
val isImplementedFakeOverride = declaration.origin == MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION
|
||||
|
||||
val isImplementedFakeOverride = newFunction != declaration || declaration.isAccessorOfImplementedFakeOverrideProperty
|
||||
|
||||
return newFunction.transformBodyIfNecessary(isImplementedFakeOverride, removedUnlinkedTypes)
|
||||
return declaration.transformBodyIfNecessary(isImplementedFakeOverride, removedUnlinkedTypes)
|
||||
}
|
||||
|
||||
override fun visitField(declaration: IrField): IrStatement {
|
||||
@@ -111,19 +90,6 @@ internal class UnlinkedDeclarationsProcessor(
|
||||
return declaration
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces an [IrProperty] or [IrSimpleFunction] that is abstract fake override in non-abstract class
|
||||
* by the corresponding non-abstract IR element.
|
||||
*/
|
||||
private fun <T : IrDeclaration> T.replaceIfUnimplementedFakeOverride(): T {
|
||||
if (this !is IrOverridableDeclaration<*> || !isFakeOverride || modality != Modality.ABSTRACT) return this
|
||||
|
||||
val clazz = parentAsClass
|
||||
if (clazz.modality == Modality.ABSTRACT || clazz.modality == Modality.SEALED) return this
|
||||
|
||||
return deepCopyWithImplementedFakeOverrides()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of all unlinked types encountered during transformation of the given [IrFunction].
|
||||
* Or empty set if there were no unlinked types.
|
||||
@@ -363,6 +329,9 @@ internal class UnlinkedDeclarationsProcessor(
|
||||
|
||||
companion object {
|
||||
private val ERROR_ORIGIN = object : IrStatementOriginImpl("LINKAGE ERROR") {}
|
||||
|
||||
val MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION =
|
||||
object : IrDeclarationOriginImpl("MISSING_ABSTRACT_CALLABLE_MEMBER_IMPLEMENTATION", isSynthetic = true) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -39,7 +39,14 @@ class JsIrLinker(
|
||||
symbol
|
||||
}) {
|
||||
|
||||
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JsManglerIr, IrTypeSystemContextImpl(builtIns), friendModules)
|
||||
override val fakeOverrideBuilder = FakeOverrideBuilder(
|
||||
linker = this,
|
||||
symbolTable = symbolTable,
|
||||
mangler = JsManglerIr,
|
||||
typeSystem = IrTypeSystemContextImpl(builtIns),
|
||||
friendModules = friendModules,
|
||||
partialLinkageEnabled = partialLinkageSupport.partialLinkageEnabled
|
||||
)
|
||||
|
||||
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
|
||||
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
|
||||
|
||||
+2
-1
@@ -160,7 +160,8 @@ fun makeSimpleFakeOverrideBuilder(
|
||||
JvmIrMangler,
|
||||
typeSystemContext,
|
||||
fakeOverrideDeclarationTable = PrePopulatedDeclarationTable(symbolDeserializer.deserializedSymbols),
|
||||
friendModules = emptyMap() // TODO: provide friend modules
|
||||
friendModules = emptyMap(), // TODO: provide friend modules
|
||||
partialLinkageEnabled = false
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -43,8 +43,14 @@ class JvmIrLinker(
|
||||
private val enableIdSignatures: Boolean,
|
||||
) : KotlinIrLinker(currentModule, messageLogger, typeSystem.irBuiltIns, symbolTable, emptyList(), partialLinkageEnabled = false) {
|
||||
|
||||
// TODO: provide friend modules
|
||||
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, JvmIrMangler, typeSystem, emptyMap())
|
||||
override val fakeOverrideBuilder = FakeOverrideBuilder(
|
||||
linker = this,
|
||||
symbolTable = symbolTable,
|
||||
mangler = JvmIrMangler,
|
||||
typeSystem = typeSystem,
|
||||
friendModules = emptyMap(), // TODO: provide friend modules
|
||||
partialLinkageEnabled = false
|
||||
)
|
||||
|
||||
private val javaName = Name.identifier("java")
|
||||
|
||||
|
||||
+10
-2
@@ -336,8 +336,16 @@ internal class KonanIrLinker(
|
||||
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor.isNativeStdlib()
|
||||
|
||||
private val forwardDeclarationDeserializer = forwardModuleDescriptor?.let { KonanForwardDeclarationModuleDeserializer(it) }
|
||||
override val fakeOverrideBuilder: FakeOverrideBuilder =
|
||||
FakeOverrideBuilder(this, symbolTable, KonanManglerIr, IrTypeSystemContextImpl(builtIns), friendModules, KonanFakeOverrideClassFilter)
|
||||
|
||||
override val fakeOverrideBuilder = FakeOverrideBuilder(
|
||||
linker = this,
|
||||
symbolTable = symbolTable,
|
||||
mangler = KonanManglerIr,
|
||||
typeSystem = IrTypeSystemContextImpl(builtIns),
|
||||
friendModules = friendModules,
|
||||
partialLinkageEnabled = partialLinkageSupport.partialLinkageEnabled,
|
||||
platformSpecificClassFilter = KonanFakeOverrideClassFilter
|
||||
)
|
||||
|
||||
val moduleDeserializers = mutableMapOf<ModuleDescriptor, KonanPartialModuleDeserializer>()
|
||||
val klibToModuleDeserializerMap = mutableMapOf<KotlinLibrary, KonanPartialModuleDeserializer>()
|
||||
|
||||
Reference in New Issue
Block a user