Generate ir-accessors for interface properties

This commit is contained in:
Michael Bogdanov
2016-09-27 12:37:31 +03:00
committed by Dmitry Petrov
parent 011ed60eee
commit f30027b4de
7 changed files with 83 additions and 17 deletions
@@ -55,7 +55,7 @@ class InterfaceDelegationLowering(val state: GenerationState) : IrElementTransfo
if (!interfaceFun.isDefinitelyNotDefaultImplsMethod()) {
val inheritedFun =
if (classDescriptor !== descriptor) {
InterfaceLowering.createDefaultImplFunDescriptor(descriptor as DefaultImplsClassDescriptorImpl, interfaceFun, classDescriptor)
InterfaceLowering.createDefaultImplFunDescriptor(descriptor as DefaultImplsClassDescriptorImpl, interfaceFun, classDescriptor, state.typeMapper)
}
else {
value
@@ -72,7 +72,7 @@ class InterfaceDelegationLowering(val state: GenerationState) : IrElementTransfo
val interfaceDescriptor = interfaceFun.containingDeclaration as ClassDescriptor
val defaultImpls = InterfaceLowering.createDefaultImplsClassDescriptor(interfaceDescriptor)
val defaultImplFun = InterfaceLowering.createDefaultImplFunDescriptor(defaultImpls, interfaceFun, interfaceDescriptor)
val defaultImplFun = InterfaceLowering.createDefaultImplFunDescriptor(defaultImpls, interfaceFun, interfaceDescriptor, state.typeMapper)
val returnType = inheritedFun.returnType!!
val irCallImpl = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, returnType, defaultImplFun, null, JvmLoweredStatementOrigin.DEFAULT_IMPLS_DELEGATION)
irBody.statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, returnType, inheritedFun, irCallImpl))
@@ -16,29 +16,21 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.jvm.ClassLoweringPass
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.codegen.isDefinitelyNotDefaultImplsMethod
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JvmAbi
@@ -53,7 +45,6 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
return
}
val interfaceDescriptor = irClass.descriptor
val defaultImplsDescriptor = createDefaultImplsClassDescriptor(interfaceDescriptor)
val defaultImplsIrClass = IrClassImpl(irClass.startOffset, irClass.endOffset, JvmLoweredDeclarationOrigin.DEFAULT_IMPLS, defaultImplsDescriptor)
@@ -64,7 +55,7 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
irClass.declarations.filterIsInstance<IrFunction>().mapNotNull {
val descriptor = it.descriptor
if (descriptor.modality != Modality.ABSTRACT) {
val functionDescriptorImpl = createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor)
val functionDescriptorImpl = createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper)
members.add(IrFunctionImpl(it.startOffset, it.endOffset, it.origin, functionDescriptorImpl, it.body))
it.body = null
@@ -87,11 +78,13 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
fun createDefaultImplFunDescriptor(
defaultImplsDescriptor: DefaultImplsClassDescriptorImpl,
descriptor: FunctionDescriptor,
interfaceDescriptor: ClassDescriptor
interfaceDescriptor: ClassDescriptor, typeMapper: KotlinTypeMapper
): SimpleFunctionDescriptorImpl {
val newFunction = SimpleFunctionDescriptorImpl.create(
defaultImplsDescriptor, AnnotationsImpl(emptyList()), descriptor.name, descriptor.kind, descriptor.source
defaultImplsDescriptor, AnnotationsImpl(emptyList()),
Name.identifier(typeMapper.mapAsmMethod(descriptor).name),
descriptor.kind, descriptor.source
)
val valueParameters =
@@ -110,7 +110,6 @@ class PropertyGenerator(val declarationGenerator: DeclarationGenerator) : Genera
val getter = property.getter ?: return null
val ktGetter = ktProperty.getter
if (DescriptorUtils.isInterface(property.containingDeclaration) && ktGetter == null) return null
val irGetter = ktGetter?.let {
IrFunctionImpl(it.startOffset, it.endOffset, IrDeclarationOrigin.DEFINED, getter)
@@ -128,7 +127,6 @@ class PropertyGenerator(val declarationGenerator: DeclarationGenerator) : Genera
val setter = property.setter ?: return null
val ktSetter = ktProperty.setter
if (DescriptorUtils.isInterface(property.containingDeclaration) && ktSetter == null) return null
val irSetter = ktSetter?.let {
IrFunctionImpl(it.startOffset, it.endOffset, IrDeclarationOrigin.DEFINED, setter)
@@ -18,9 +18,39 @@ FILE /delegatedImplementation.kt
BLOCK_BODY
CLASS INTERFACE IOther
PROPERTY public abstract val x: kotlin.String
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun <get-x>(): kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-x>(): String'
GET_FIELD 'x: String' type=kotlin.String origin=null
receiver: THIS of 'IOther' type=IOther
PROPERTY public abstract var y: kotlin.Int
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun <get-y>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-y>(): Int'
GET_FIELD 'y: Int' type=kotlin.Int origin=null
receiver: THIS of 'IOther' type=IOther
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun <set-y>(<set-?>: kotlin.Int): kotlin.Unit
BLOCK_BODY
SET_FIELD 'y: Int' type=kotlin.Unit origin=null
receiver: THIS of 'IOther' type=IOther
value: GET_VAR 'value-parameter <set-?>: Int' type=kotlin.Int origin=null
PROPERTY public abstract val kotlin.Byte.z1: kotlin.Int
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun kotlin.Byte.<get-z1>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-z1>() on Byte: Int'
GET_FIELD 'z1: Int on Byte' type=kotlin.Int origin=null
receiver: THIS of 'IOther' type=IOther
PROPERTY public abstract var kotlin.Byte.z2: kotlin.Int
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun kotlin.Byte.<get-z2>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-z2>() on Byte: Int'
GET_FIELD 'z2: Int on Byte' type=kotlin.Int origin=null
receiver: THIS of 'IOther' type=IOther
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun kotlin.Byte.<set-z2>(<set-?>: kotlin.Int): kotlin.Unit
BLOCK_BODY
SET_FIELD 'z2: Int on Byte' type=kotlin.Unit origin=null
receiver: THIS of 'IOther' type=IOther
value: GET_VAR 'value-parameter <set-?>: Int' type=kotlin.Int origin=null
FUN public fun otherImpl(x0: kotlin.String, y0: kotlin.Int): IOther
BLOCK_BODY
RETURN type=kotlin.Nothing from='otherImpl(String, Int): IOther'
@@ -0,0 +1,8 @@
// WITH_RUNTIME
interface C {
val test1: Int
val test2: Int get() = 0
var test3: Int
var test4: Int get() = 0; set(value) {}
}
@@ -0,0 +1,31 @@
FILE /interfaceProperties.kt
CLASS INTERFACE C
PROPERTY public abstract val test1: kotlin.Int
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun <get-test1>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test1>(): Int'
GET_FIELD 'test1: Int' type=kotlin.Int origin=null
receiver: THIS of 'C' type=C
PROPERTY public open val test2: kotlin.Int
FUN public open fun <get-test2>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test2>(): Int'
CONST Int type=kotlin.Int value='0'
PROPERTY public abstract var test3: kotlin.Int
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun <get-test3>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test3>(): Int'
GET_FIELD 'test3: Int' type=kotlin.Int origin=null
receiver: THIS of 'C' type=C
FUN DEFAULT_PROPERTY_ACCESSOR public abstract fun <set-test3>(<set-?>: kotlin.Int): kotlin.Unit
BLOCK_BODY
SET_FIELD 'test3: Int' type=kotlin.Unit origin=null
receiver: THIS of 'C' type=C
value: GET_VAR 'value-parameter <set-?>: Int' type=kotlin.Int origin=null
PROPERTY public open var test4: kotlin.Int
FUN public open fun <get-test4>(): kotlin.Int
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test4>(): Int'
CONST Int type=kotlin.Int value='0'
FUN public open fun <set-test4>(value: kotlin.Int): kotlin.Unit
BLOCK_BODY
@@ -214,6 +214,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("interfaceProperties.kt")
public void testInterfaceProperties() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/interfaceProperties.kt");
doTest(fileName);
}
@TestMetadata("localDelegatedProperties.kt")
public void testLocalDelegatedProperties() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/declarations/localDelegatedProperties.kt");