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,
modality: Modality = Modality.FINAL,
visibility: Visibility = oldFunction.visibility,
isFakeOverride: Boolean = oldFunction.isFakeOverride,
copyMetadata: Boolean = true,
typeParametersFromContext: List<IrTypeParameter> = listOf()
): IrSimpleFunction {
@@ -579,7 +580,7 @@ fun createStaticFunctionWithReceivers(
isTailrec = false,
isSuspend = oldFunction.isSuspend,
isExpect = oldFunction.isExpect,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
isFakeOverride = isFakeOverride,
isOperator = oldFunction is IrSimpleFunction && oldFunction.isOperator
).apply {
descriptor.bind(this)
@@ -425,7 +425,7 @@ private fun IrFunction.generateDefaultsFunction(
if (this is IrSimpleFunction) {
// 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 })
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.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
// binaries, it's way too late to fix it. Hence the workaround.
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.defaultArgumentsOriginalFunction[it] = this
}
@@ -464,7 +466,8 @@ private fun IrFunction.generateDefaultsFunction(
private fun IrFunction.generateDefaultsFunctionImpl(
context: CommonBackendContext,
newOrigin: IrDeclarationOrigin,
newVisibility: Visibility
newVisibility: Visibility,
isFakeOverride: Boolean
): IrFunction {
val newFunction = when (this) {
is IrConstructor ->
@@ -481,6 +484,7 @@ private fun IrFunction.generateDefaultsFunctionImpl(
updateFrom(this@generateDefaultsFunctionImpl)
name = Name.identifier("${this@generateDefaultsFunctionImpl.name}\$default")
origin = newOrigin
this.isFakeOverride = isFakeOverride
modality = Modality.FINAL
isExternal = 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(
startOffset, endOffset, origin,
IrFieldSymbolImpl(wrappedDescriptor),
name, type, visibility, isFinal, isExternal, isStatic,
origin == IrDeclarationOrigin.FAKE_OVERRIDE
name, type, visibility, isFinal, isExternal, isStatic, isFakeOverride
).also {
it.metadata = metadata
wrappedDescriptor.bind(it)
@@ -81,7 +80,7 @@ fun IrPropertyBuilder.buildProperty(): IrProperty {
IrPropertySymbolImpl(wrappedDescriptor),
name, visibility, modality,
isVar = isVar, isConst = isConst, isLateinit = isLateinit, isDelegated = isDelegated, isExpect = isExpect, isExternal = isExternal,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
isFakeOverride = isFakeOverride
).also {
wrappedDescriptor.bind(it)
}
@@ -133,8 +132,7 @@ fun IrFunctionBuilder.buildFun(originalDescriptor: FunctionDescriptor? = null):
IrSimpleFunctionSymbolImpl(wrappedDescriptor),
name, visibility, modality, returnType,
isInline = isInline, isExternal = isExternal, isTailrec = isTailrec, isSuspend = isSuspend, isExpect = isExpect,
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
isOperator = isOperator
isFakeOverride = isFakeOverride, isOperator = isOperator
).also {
wrappedDescriptor.bind(it)
}
@@ -183,6 +181,7 @@ fun IrDeclarationContainer.addFunction(
visibility: Visibility = Visibilities.PUBLIC,
isStatic: Boolean = false,
isSuspend: Boolean = false,
isFakeOverride: Boolean = false,
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
): IrSimpleFunction =
addFunction {
@@ -191,6 +190,7 @@ fun IrDeclarationContainer.addFunction(
this.modality = modality
this.visibility = visibility
this.isSuspend = isSuspend
this.isFakeOverride = isFakeOverride
this.origin = origin
}.apply {
if (!isStatic) {
@@ -180,8 +180,8 @@ class JvmDeclarationFactory(
fun getStaticBackingField(irProperty: IrProperty): IrField? {
// Only fields defined directly in objects should be made static.
// Fake overrides never point to those, as objects are final.
if (irProperty.isFakeOverride) return null
val oldField = irProperty.backingField ?: return null
if (oldField.isFakeOverride) return null
val oldParent = irProperty.parent as? IrClass ?: return null
if (!oldParent.isObject) return null
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.
visibility = if (interfaceFun.visibility == Visibilities.PRIVATE) Visibilities.PRIVATE else Visibilities.PUBLIC,
isFakeOverride = false,
typeParametersFromContext = parent.typeParameters
)
}
@@ -270,7 +271,6 @@ class JvmDeclarationFactory(
fun getDefaultImplsRedirection(fakeOverride: IrSimpleFunction): IrSimpleFunction =
defaultImplsRedirections.getOrPut(fakeOverride) {
assert(fakeOverride.origin == IrDeclarationOrigin.FAKE_OVERRIDE)
assert(fakeOverride.isFakeOverride)
val irClass = fakeOverride.parentAsClass
val descriptor = DescriptorsToIrRemapper.remapDeclaredSimpleFunction(fakeOverride.descriptor)
@@ -527,6 +527,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
irFunction.name.toSuspendImplementationName(),
irFunction,
origin = JvmLoweredDeclarationOrigin.SUSPEND_IMPL_STATIC_FUNCTION,
isFakeOverride = false,
copyMetadata = false
)
static.body = irFunction.moveBodyTo(static)
@@ -333,6 +333,7 @@ private class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass,
origin = IrDeclarationOrigin.DEFINED
name = irFunction.name
returnType = irFunction.returnType
isFakeOverride = false
}.apply {
copyParametersWithErasure(this@addAbstractMethodStub, irFunction, needsArgumentBoxing)
}
@@ -153,6 +153,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
val fakeOverrideReceiverField = functionReferenceClass.addField {
name = receiverFieldFromSuper.name
isFakeOverride = true
origin = IrDeclarationOrigin.FAKE_OVERRIDE
type = receiverFieldFromSuper.type
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.impl.IrCallImpl
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.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -215,19 +216,21 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded(
val function = buildFun {
updateFrom(target)
origin = if (shouldGeneratePartHierarchy) IrDeclarationOrigin.FAKE_OVERRIDE else JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE
isFakeOverride = shouldGeneratePartHierarchy
name = target.name
}
function.copyParameterDeclarationsFrom(target)
function.returnType = target.returnType
function.returnType = target.returnType.substitute(target.typeParameters, function.typeParameters.map { it.defaultType })
function.parent = facadeClass
function.annotations = target.annotations
function.annotations = target.annotations.map { it.deepCopyWithSymbols() }
if (shouldGeneratePartHierarchy) {
function.origin = IrDeclarationOrigin.FAKE_OVERRIDE
function.body = null
function.overriddenSymbols = listOf(symbol)
} else {
function.origin = JvmLoweredDeclarationOrigin.MULTIFILE_BRIDGE
function.overriddenSymbols = overriddenSymbols.toList()
function.body = context.createIrBuilder(function.symbol).irBlockBody {
+irReturn(irCall(target).also { call ->
@@ -139,6 +139,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
name = method.name
returnType = method.returnType
visibility = method.visibility
isFakeOverride = true
origin = IrDeclarationOrigin.FAKE_OVERRIDE
}.apply {
overriddenSymbols += method.symbol
@@ -290,6 +291,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
val receiverField = referenceClass.addField {
name = backingFieldFromSuper.name
isFakeOverride = true
origin = IrDeclarationOrigin.FAKE_OVERRIDE
type = backingFieldFromSuper.type
isFinal = backingFieldFromSuper.isFinal
@@ -146,7 +146,7 @@ class MemoizedInlineClassReplacements {
}
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>()
for ((index, parameter) in function.explicitParameters.withIndex()) {
newValueParameters += when (parameter) {
@@ -171,7 +171,12 @@ class MemoizedInlineClassReplacements {
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) {
updateFrom(function)
origin = if (function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER) {
@@ -179,6 +184,9 @@ class MemoizedInlineClassReplacements {
} else {
replacementOrigin
}
if (noFakeOverride) {
isFakeOverride = false
}
name = mangledNameFor(function)
returnType = function.returnType
}.apply {
@@ -16,6 +16,7 @@ class IrFieldBuilder : IrDeclarationBuilder() {
var isFinal: Boolean = false
var isExternal: Boolean = false
var isStatic: Boolean = false
var isFakeOverride: Boolean = false
var metadata: MetadataSource.Property? = null
fun updateFrom(from: IrField) {
@@ -25,6 +26,7 @@ class IrFieldBuilder : IrDeclarationBuilder() {
isFinal = from.isFinal
isExternal = from.isExternal
isStatic = from.isStatic
isFakeOverride = from.isFakeOverride
metadata = from.metadata
}
}
@@ -27,6 +27,8 @@ class IrFunctionBuilder : IrDeclarationBuilder() {
var isPrimary: Boolean = false
var isFakeOverride: Boolean = false
fun updateFrom(from: IrFunction) {
super.updateFrom(from)
@@ -39,6 +41,7 @@ class IrFunctionBuilder : IrDeclarationBuilder() {
isTailrec = from.isTailrec
isSuspend = from.isSuspend
isOperator = from.isOperator
isFakeOverride = from.isFakeOverride
} else {
modality = Modality.FINAL
isTailrec = false
@@ -16,4 +16,5 @@ class IrPropertyBuilder : IrDeclarationBuilder() {
var isDelegated: Boolean = false
var isExternal: Boolean = false
var isExpect: Boolean = false
var isFakeOverride: Boolean = false
}