JVM IR: Fix corresponding properties for default impls redirections

This commit is contained in:
Steven Schäfer
2020-04-20 17:22:46 +02:00
committed by Alexander Udalov
parent 1fafbb8d72
commit 4a2b5df9fa
5 changed files with 54 additions and 27 deletions
@@ -73,8 +73,11 @@ fun IrClass.addField(fieldName: Name, fieldType: IrType, fieldVisibility: Visibi
fun IrClass.addField(fieldName: String, fieldType: IrType, fieldVisibility: Visibility = Visibilities.PRIVATE): IrField =
addField(Name.identifier(fieldName), fieldType, fieldVisibility)
fun IrPropertyBuilder.buildProperty(): IrProperty {
val wrappedDescriptor = WrappedPropertyDescriptor()
fun IrPropertyBuilder.buildProperty(originalDescriptor: PropertyDescriptor? = null): IrProperty {
val wrappedDescriptor = when (originalDescriptor) {
is DescriptorWithContainerSource -> WrappedPropertyDescriptorWithContainerSource(originalDescriptor.containerSource)
else -> WrappedPropertyDescriptor()
}
return IrPropertyImpl(
startOffset, endOffset, origin,
IrPropertySymbolImpl(wrappedDescriptor),
@@ -86,14 +89,14 @@ fun IrPropertyBuilder.buildProperty(): IrProperty {
}
}
inline fun buildProperty(builder: IrPropertyBuilder.() -> Unit) =
inline fun buildProperty(originalDescriptor: PropertyDescriptor? = null, builder: IrPropertyBuilder.() -> Unit) =
IrPropertyBuilder().run {
builder()
buildProperty()
buildProperty(originalDescriptor)
}
inline fun IrDeclarationContainer.addProperty(builder: IrPropertyBuilder.() -> Unit): IrProperty =
buildProperty(builder).also { property ->
inline fun IrDeclarationContainer.addProperty(originalDescriptor: PropertyDescriptor? = null, builder: IrPropertyBuilder.() -> Unit): IrProperty =
buildProperty(originalDescriptor, builder).also { property ->
declarations.add(property)
property.parent = this@addProperty
}
@@ -120,7 +123,7 @@ inline fun IrProperty.addSetter(builder: IrFunctionBuilder.() -> Unit = {}): IrS
}
fun IrFunctionBuilder.buildFun(originalDescriptor: FunctionDescriptor? = null): IrFunctionImpl {
val wrappedDescriptor = when(originalDescriptor) {
val wrappedDescriptor = when (originalDescriptor) {
is DescriptorWithContainerSource -> WrappedFunctionDescriptorWithContainerSource(originalDescriptor.containerSource)
is PropertyGetterDescriptor -> WrappedPropertyGetterDescriptor(originalDescriptor.annotations, originalDescriptor.source)
is PropertySetterDescriptor -> WrappedPropertySetterDescriptor(originalDescriptor.annotations, originalDescriptor.source)
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.MethodSignatureMapper
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.copyCorrespondingPropertyFrom
import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject
import org.jetbrains.kotlin.codegen.AsmUtil
@@ -22,12 +23,18 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.setSourceRange
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.descriptors.WrappedClassConstructorDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi
@@ -292,23 +299,7 @@ class JvmDeclarationFactory(
overriddenSymbols = fakeOverride.overriddenSymbols
copyParameterDeclarationsFrom(fakeOverride)
annotations = fakeOverride.annotations
fakeOverride.correspondingPropertySymbol?.owner?.let { fakeOverrideProperty ->
// NB: property is only generated for the sake of the type mapper.
// If both setter and getter are present, original property will be duplicated.
val newPropertyDescriptor = DescriptorsToIrRemapper.remapDeclaredProperty(fakeOverrideProperty.descriptor)
correspondingPropertySymbol = with(fakeOverrideProperty) {
IrPropertyImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
IrDeclarationOrigin.DEFINED, IrPropertySymbolImpl(newPropertyDescriptor),
name, visibility, modality, isVar, isConst, isLateinit, isDelegated,
isExternal = false,
isExpect = isExpect
).apply {
newPropertyDescriptor.bind(this)
parent = irClass
}.symbol
}
}
copyCorrespondingPropertyFrom(fakeOverride)
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOT
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.*
@@ -319,3 +320,22 @@ fun firstSuperMethodFromKotlin(
owner.modality != Modality.ABSTRACT && owner.overrides(implementation)
}
}
// MethodSignatureMapper uses the corresponding property of a function to determine correct names
// for property accessors.
fun IrSimpleFunction.copyCorrespondingPropertyFrom(source: IrSimpleFunction) {
val property = source.correspondingPropertySymbol?.owner ?: return
val target = this
correspondingPropertySymbol = buildProperty(property.symbol.descriptor) {
name = property.name
updateFrom(property)
}.apply {
parent = target.parent
when {
source.isGetter -> getter = target
source.isSetter -> setter = target
else -> error("Orphaned property getter/setter: ${source.render()}")
}
}.symbol
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.ir.builders.declarations
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrProperty
class IrPropertyBuilder : IrDeclarationBuilder() {
var modality: Modality = Modality.FINAL
@@ -17,4 +18,16 @@ class IrPropertyBuilder : IrDeclarationBuilder() {
var isExternal: Boolean = false
var isExpect: Boolean = false
var isFakeOverride: Boolean = false
fun updateFrom(from: IrProperty) {
super.updateFrom(from)
isVar = from.isVar
isConst = from.isConst
isLateinit = from.isLateinit
isDelegated = from.isDelegated
isExternal = from.isExternal
isExpect = from.isExpect
isFakeOverride = from.isFakeOverride
}
}
@@ -872,7 +872,7 @@ open class WrappedPropertyDescriptor(
}
class WrappedPropertyDescriptorWithContainerSource(
override var containerSource: DeserializedContainerSource
override var containerSource: DeserializedContainerSource?
) : WrappedPropertyDescriptor(), DescriptorWithContainerSource
abstract class WrappedPropertyAccessorDescriptor(annotations: Annotations, sourceElement: SourceElement) :