IR: explicitly pass isFakeOverride to buildFun and friends

This commit is contained in:
Georgy Bronnikov
2020-03-27 18:41:20 +03:00
committed by romanart
parent fb6956f842
commit 5fe28b3179
14 changed files with 44 additions and 17 deletions
@@ -560,6 +560,7 @@ fun createStaticFunctionWithReceivers(
origin: IrDeclarationOrigin = oldFunction.origin, origin: IrDeclarationOrigin = oldFunction.origin,
modality: Modality = Modality.FINAL, modality: Modality = Modality.FINAL,
visibility: Visibility = oldFunction.visibility, visibility: Visibility = oldFunction.visibility,
isFakeOverride: Boolean = oldFunction.isFakeOverride,
copyMetadata: Boolean = true, copyMetadata: Boolean = true,
typeParametersFromContext: List<IrTypeParameter> = listOf() typeParametersFromContext: List<IrTypeParameter> = listOf()
): IrSimpleFunction { ): IrSimpleFunction {
@@ -579,7 +580,7 @@ fun createStaticFunctionWithReceivers(
isTailrec = false, isTailrec = false,
isSuspend = oldFunction.isSuspend, isSuspend = oldFunction.isSuspend,
isExpect = oldFunction.isExpect, isExpect = oldFunction.isExpect,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE, isFakeOverride = isFakeOverride,
isOperator = oldFunction is IrSimpleFunction && oldFunction.isOperator isOperator = oldFunction is IrSimpleFunction && oldFunction.isOperator
).apply { ).apply {
descriptor.bind(this) descriptor.bind(this)
@@ -425,7 +425,7 @@ private fun IrFunction.generateDefaultsFunction(
if (this is IrSimpleFunction) { if (this is IrSimpleFunction) {
// If this is an override of a function with default arguments, produce a fake override of a default stub. // If this is an override of a function with default arguments, produce a fake override of a default stub.
if (overriddenSymbols.any { it.owner.findBaseFunctionWithDefaultArguments(skipInlineMethods, skipExternalMethods) != null }) if (overriddenSymbols.any { it.owner.findBaseFunctionWithDefaultArguments(skipInlineMethods, skipExternalMethods) != null })
return generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FAKE_OVERRIDE, visibility).also { return generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FAKE_OVERRIDE, visibility, isFakeOverride = true).also {
context.mapping.defaultArgumentsDispatchFunction[this] = it context.mapping.defaultArgumentsDispatchFunction[this] = it
context.mapping.defaultArgumentsOriginalFunction[it] = this context.mapping.defaultArgumentsOriginalFunction[it] = this
@@ -453,7 +453,9 @@ private fun IrFunction.generateDefaultsFunction(
// Since this bug causes the metadata serializer to write the "has default value" flag into compiled // Since this bug causes the metadata serializer to write the "has default value" flag into compiled
// binaries, it's way too late to fix it. Hence the workaround. // binaries, it's way too late to fix it. Hence the workaround.
if (valueParameters.any { it.defaultValue != null }) { if (valueParameters.any { it.defaultValue != null }) {
return generateDefaultsFunctionImpl(context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER, visibility).also { return generateDefaultsFunctionImpl(
context, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER, visibility, isFakeOverride = false
).also {
context.mapping.defaultArgumentsDispatchFunction[this] = it context.mapping.defaultArgumentsDispatchFunction[this] = it
context.mapping.defaultArgumentsOriginalFunction[it] = this context.mapping.defaultArgumentsOriginalFunction[it] = this
} }
@@ -464,7 +466,8 @@ private fun IrFunction.generateDefaultsFunction(
private fun IrFunction.generateDefaultsFunctionImpl( private fun IrFunction.generateDefaultsFunctionImpl(
context: CommonBackendContext, context: CommonBackendContext,
newOrigin: IrDeclarationOrigin, newOrigin: IrDeclarationOrigin,
newVisibility: Visibility newVisibility: Visibility,
isFakeOverride: Boolean
): IrFunction { ): IrFunction {
val newFunction = when (this) { val newFunction = when (this) {
is IrConstructor -> is IrConstructor ->
@@ -481,6 +484,7 @@ private fun IrFunction.generateDefaultsFunctionImpl(
updateFrom(this@generateDefaultsFunctionImpl) updateFrom(this@generateDefaultsFunctionImpl)
name = Name.identifier("${this@generateDefaultsFunctionImpl.name}\$default") name = Name.identifier("${this@generateDefaultsFunctionImpl.name}\$default")
origin = newOrigin origin = newOrigin
this.isFakeOverride = isFakeOverride
modality = Modality.FINAL modality = Modality.FINAL
isExternal = false isExternal = false
isTailrec = false isTailrec = false
@@ -213,4 +213,4 @@ private fun CommonBackendContext.buildOrGetNullableField(originalField: IrField)
} }
} }
private val IrProperty.isRealLateinit get() = isLateinit && getter?.isFakeOverride != true private val IrProperty.isRealLateinit get() = isLateinit && !isFakeOverride
@@ -44,8 +44,7 @@ fun IrFieldBuilder.buildField(): IrField {
return IrFieldImpl( return IrFieldImpl(
startOffset, endOffset, origin, startOffset, endOffset, origin,
IrFieldSymbolImpl(wrappedDescriptor), IrFieldSymbolImpl(wrappedDescriptor),
name, type, visibility, isFinal, isExternal, isStatic, name, type, visibility, isFinal, isExternal, isStatic, isFakeOverride
origin == IrDeclarationOrigin.FAKE_OVERRIDE
).also { ).also {
it.metadata = metadata it.metadata = metadata
wrappedDescriptor.bind(it) wrappedDescriptor.bind(it)
@@ -81,7 +80,7 @@ fun IrPropertyBuilder.buildProperty(): IrProperty {
IrPropertySymbolImpl(wrappedDescriptor), IrPropertySymbolImpl(wrappedDescriptor),
name, visibility, modality, name, visibility, modality,
isVar = isVar, isConst = isConst, isLateinit = isLateinit, isDelegated = isDelegated, isExpect = isExpect, isExternal = isExternal, isVar = isVar, isConst = isConst, isLateinit = isLateinit, isDelegated = isDelegated, isExpect = isExpect, isExternal = isExternal,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE isFakeOverride = isFakeOverride
).also { ).also {
wrappedDescriptor.bind(it) wrappedDescriptor.bind(it)
} }
@@ -133,8 +132,7 @@ fun IrFunctionBuilder.buildFun(originalDescriptor: FunctionDescriptor? = null):
IrSimpleFunctionSymbolImpl(wrappedDescriptor), IrSimpleFunctionSymbolImpl(wrappedDescriptor),
name, visibility, modality, returnType, name, visibility, modality, returnType,
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect, isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE, isFakeOverride = isFakeOverride, isOperator = isOperator
isOperator = isOperator
).also { ).also {
wrappedDescriptor.bind(it) wrappedDescriptor.bind(it)
} }
@@ -183,6 +181,7 @@ fun IrDeclarationContainer.addFunction(
visibility: Visibility = Visibilities.PUBLIC, visibility: Visibility = Visibilities.PUBLIC,
isStatic: Boolean = false, isStatic: Boolean = false,
isSuspend: Boolean = false, isSuspend: Boolean = false,
isFakeOverride: Boolean = false,
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
): IrSimpleFunction = ): IrSimpleFunction =
addFunction { addFunction {
@@ -191,6 +190,7 @@ fun IrDeclarationContainer.addFunction(
this.modality = modality this.modality = modality
this.visibility = visibility this.visibility = visibility
this.isSuspend = isSuspend this.isSuspend = isSuspend
this.isFakeOverride = isFakeOverride
this.origin = origin this.origin = origin
}.apply { }.apply {
if (!isStatic) { if (!isStatic) {
@@ -180,8 +180,8 @@ class JvmDeclarationFactory(
fun getStaticBackingField(irProperty: IrProperty): IrField? { fun getStaticBackingField(irProperty: IrProperty): IrField? {
// Only fields defined directly in objects should be made static. // Only fields defined directly in objects should be made static.
// Fake overrides never point to those, as objects are final. // Fake overrides never point to those, as objects are final.
if (irProperty.isFakeOverride) return null
val oldField = irProperty.backingField ?: return null val oldField = irProperty.backingField ?: return null
if (oldField.isFakeOverride) return null
val oldParent = irProperty.parent as? IrClass ?: return null val oldParent = irProperty.parent as? IrClass ?: return null
if (!oldParent.isObject) return null if (!oldParent.isObject) return null
return staticBackingFields.getOrPut(irProperty) { return staticBackingFields.getOrPut(irProperty) {
@@ -238,6 +238,7 @@ class JvmDeclarationFactory(
// We should rather not generate a bridge to clone when interface inherits from Cloneable at all. // We should rather not generate a bridge to clone when interface inherits from Cloneable at all.
visibility = if (interfaceFun.visibility == Visibilities.PRIVATE) Visibilities.PRIVATE else Visibilities.PUBLIC, visibility = if (interfaceFun.visibility == Visibilities.PRIVATE) Visibilities.PRIVATE else Visibilities.PUBLIC,
isFakeOverride = false,
typeParametersFromContext = parent.typeParameters typeParametersFromContext = parent.typeParameters
) )
} }
@@ -270,7 +271,6 @@ class JvmDeclarationFactory(
fun getDefaultImplsRedirection(fakeOverride: IrSimpleFunction): IrSimpleFunction = fun getDefaultImplsRedirection(fakeOverride: IrSimpleFunction): IrSimpleFunction =
defaultImplsRedirections.getOrPut(fakeOverride) { defaultImplsRedirections.getOrPut(fakeOverride) {
assert(fakeOverride.origin == IrDeclarationOrigin.FAKE_OVERRIDE)
assert(fakeOverride.isFakeOverride) assert(fakeOverride.isFakeOverride)
val irClass = fakeOverride.parentAsClass val irClass = fakeOverride.parentAsClass
val descriptor = DescriptorsToIrRemapper.remapDeclaredSimpleFunction(fakeOverride.descriptor) val descriptor = DescriptorsToIrRemapper.remapDeclaredSimpleFunction(fakeOverride.descriptor)
@@ -527,6 +527,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
irFunction.name.toSuspendImplementationName(), irFunction.name.toSuspendImplementationName(),
irFunction, irFunction,
origin = JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION, origin = JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION,
isFakeOverride = false,
copyMetadata = false copyMetadata = false
) )
static.body = irFunction.moveBodyTo(static) static.body = irFunction.moveBodyTo(static)
@@ -333,6 +333,7 @@ private class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass,
origin = IrDeclarationOrigin.DEFINED origin = IrDeclarationOrigin.DEFINED
name = irFunction.name name = irFunction.name
returnType = irFunction.returnType returnType = irFunction.returnType
isFakeOverride = false
}.apply { }.apply {
copyParametersWithErasure(this@addAbstractMethodStub, irFunction, needsArgumentBoxing) copyParametersWithErasure(this@addAbstractMethodStub, irFunction, needsArgumentBoxing)
} }
@@ -153,6 +153,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
val fakeOverrideReceiverField = functionReferenceClass.addField { val fakeOverrideReceiverField = functionReferenceClass.addField {
name = receiverFieldFromSuper.name name = receiverFieldFromSuper.name
isFakeOverride = true
origin = IrDeclarationOrigin.FAKE_OVERRIDE origin = IrDeclarationOrigin.FAKE_OVERRIDE
type = receiverFieldFromSuper.type type = receiverFieldFromSuper.type
isFinal = receiverFieldFromSuper.isFinal isFinal = receiverFieldFromSuper.isFinal
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -215,19 +216,21 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded(
val function = buildFun { val function = buildFun {
updateFrom(target) updateFrom(target)
origin = if (shouldGeneratePartHierarchy) IrDeclarationOrigin.FAKE_OVERRIDE else JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE isFakeOverride = shouldGeneratePartHierarchy
name = target.name name = target.name
} }
function.copyParameterDeclarationsFrom(target) function.copyParameterDeclarationsFrom(target)
function.returnType = target.returnType function.returnType = target.returnType.substitute(target.typeParameters, function.typeParameters.map { it.defaultType })
function.parent = facadeClass function.parent = facadeClass
function.annotations = target.annotations function.annotations = target.annotations.map { it.deepCopyWithSymbols() }
if (shouldGeneratePartHierarchy) { if (shouldGeneratePartHierarchy) {
function.origin = IrDeclarationOrigin.FAKE_OVERRIDE
function.body = null function.body = null
function.overriddenSymbols = listOf(symbol) function.overriddenSymbols = listOf(symbol)
} else { } else {
function.origin = JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE
function.overriddenSymbols = overriddenSymbols.toList() function.overriddenSymbols = overriddenSymbols.toList()
function.body = context.createIrBuilder(function.symbol).irBlockBody { function.body = context.createIrBuilder(function.symbol).irBlockBody {
+irReturn(irCall(target).also { call -> +irReturn(irCall(target).also { call ->
@@ -139,6 +139,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
name = method.name name = method.name
returnType = method.returnType returnType = method.returnType
visibility = method.visibility visibility = method.visibility
isFakeOverride = true
origin = IrDeclarationOrigin.FAKE_OVERRIDE origin = IrDeclarationOrigin.FAKE_OVERRIDE
}.apply { }.apply {
overriddenSymbols += method.symbol overriddenSymbols += method.symbol
@@ -290,6 +291,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
val receiverField = referenceClass.addField { val receiverField = referenceClass.addField {
name = backingFieldFromSuper.name name = backingFieldFromSuper.name
isFakeOverride = true
origin = IrDeclarationOrigin.FAKE_OVERRIDE origin = IrDeclarationOrigin.FAKE_OVERRIDE
type = backingFieldFromSuper.type type = backingFieldFromSuper.type
isFinal = backingFieldFromSuper.isFinal isFinal = backingFieldFromSuper.isFinal
@@ -146,7 +146,7 @@ class MemoizedInlineClassReplacements {
} }
private fun createStaticReplacement(function: IrFunction): IrSimpleFunction = private fun createStaticReplacement(function: IrFunction): IrSimpleFunction =
buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT) { buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT, noFakeOverride = true) {
val newValueParameters = ArrayList<IrValueParameter>() val newValueParameters = ArrayList<IrValueParameter>()
for ((index, parameter) in function.explicitParameters.withIndex()) { for ((index, parameter) in function.explicitParameters.withIndex()) {
newValueParameters += when (parameter) { newValueParameters += when (parameter) {
@@ -171,7 +171,12 @@ class MemoizedInlineClassReplacements {
valueParameters = newValueParameters valueParameters = newValueParameters
} }
private fun buildReplacement(function: IrFunction, replacementOrigin: IrDeclarationOrigin, body: IrFunctionImpl.() -> Unit) = private fun buildReplacement(
function: IrFunction,
replacementOrigin: IrDeclarationOrigin,
noFakeOverride: Boolean = false,
body: IrFunctionImpl.() -> Unit
) =
buildFunWithDescriptorForInlining(function.descriptor) { buildFunWithDescriptorForInlining(function.descriptor) {
updateFrom(function) updateFrom(function)
origin = if (function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER) { origin = if (function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER) {
@@ -179,6 +184,9 @@ class MemoizedInlineClassReplacements {
} else { } else {
replacementOrigin replacementOrigin
} }
if (noFakeOverride) {
isFakeOverride = false
}
name = mangledNameFor(function) name = mangledNameFor(function)
returnType = function.returnType returnType = function.returnType
}.apply { }.apply {
@@ -16,6 +16,7 @@ class IrFieldBuilder : IrDeclarationBuilder() {
var isFinal: Boolean = false var isFinal: Boolean = false
var isExternal: Boolean = false var isExternal: Boolean = false
var isStatic: Boolean = false var isStatic: Boolean = false
var isFakeOverride: Boolean = false
var metadata: MetadataSource.Property? = null var metadata: MetadataSource.Property? = null
fun updateFrom(from: IrField) { fun updateFrom(from: IrField) {
@@ -25,6 +26,7 @@ class IrFieldBuilder : IrDeclarationBuilder() {
isFinal = from.isFinal isFinal = from.isFinal
isExternal = from.isExternal isExternal = from.isExternal
isStatic = from.isStatic isStatic = from.isStatic
isFakeOverride = from.isFakeOverride
metadata = from.metadata metadata = from.metadata
} }
} }
@@ -27,6 +27,8 @@ class IrFunctionBuilder : IrDeclarationBuilder() {
var isPrimary: Boolean = false var isPrimary: Boolean = false
var isFakeOverride: Boolean = false
fun updateFrom(from: IrFunction) { fun updateFrom(from: IrFunction) {
super.updateFrom(from) super.updateFrom(from)
@@ -39,6 +41,7 @@ class IrFunctionBuilder : IrDeclarationBuilder() {
isTailrec = from.isTailrec isTailrec = from.isTailrec
isSuspend = from.isSuspend isSuspend = from.isSuspend
isOperator = from.isOperator isOperator = from.isOperator
isFakeOverride = from.isFakeOverride
} else { } else {
modality = Modality.FINAL modality = Modality.FINAL
isTailrec = false isTailrec = false
@@ -16,4 +16,5 @@ class IrPropertyBuilder : IrDeclarationBuilder() {
var isDelegated: Boolean = false var isDelegated: Boolean = false
var isExternal: Boolean = false var isExternal: Boolean = false
var isExpect: Boolean = false var isExpect: Boolean = false
var isFakeOverride: Boolean = false
} }