Properties without accessors are generated as

IrGetBackingField / IrSetBackingField expressions.
This commit is contained in:
Dmitry Petrov
2016-09-05 15:06:38 +03:00
committed by Dmitry Petrov
parent a1ad828ea8
commit ceeccfa1b7
40 changed files with 359 additions and 122 deletions
@@ -22,6 +22,7 @@ const val ARGUMENT0_SLOT = 0
const val ARGUMENT1_SLOT = 1
const val DISPATCH_RECEIVER_SLOT = -1
const val EXTENSION_RECEIVER_SLOT = -2
const val BACKING_FIELD_RECEIVER_SLOT = -1
const val FUNCTION_BODY_SLOT = -1
const val ANONYMOUS_INITIALIZER_BODY_SLOT = -1
const val MODULE_SLOT = 0
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -24,6 +25,8 @@ import org.jetbrains.kotlin.types.typeUtil.builtIns
interface IrBackingFieldExpression : IrDeclarationReference {
override val descriptor: PropertyDescriptor
val superQualifier: ClassDescriptor?
var receiver: IrExpression?
val operator: IrOperator?
}
@@ -38,20 +41,54 @@ abstract class IrBackingFieldExpressionBase(
endOffset: Int,
descriptor: PropertyDescriptor,
type: KotlinType,
override val operator: IrOperator? = null
) : IrDeclarationReferenceBase<PropertyDescriptor>(startOffset, endOffset, type, descriptor), IrBackingFieldExpression
override val operator: IrOperator? = null,
override val superQualifier: ClassDescriptor? = null
) : IrDeclarationReferenceBase<PropertyDescriptor>(startOffset, endOffset, type, descriptor), IrBackingFieldExpression {
override final var receiver: IrExpression? = null
set(value) {
value?.assertDetached()
field?.detach()
field = value
value?.setTreeLocation(this, BACKING_FIELD_RECEIVER_SLOT)
}
override fun getChild(slot: Int): IrElement? =
when (slot) {
BACKING_FIELD_RECEIVER_SLOT -> receiver
else -> null
}
override fun replaceChild(slot: Int, newChild: IrElement) {
when (slot) {
BACKING_FIELD_RECEIVER_SLOT -> receiver = newChild.assertCast()
else -> throwNoSuchSlot(slot)
}
}
}
class IrGetBackingFieldImpl(
startOffset: Int,
endOffset: Int,
descriptor: PropertyDescriptor,
operator: IrOperator? = null
) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type, operator), IrGetBackingField {
operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null
) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type, operator, superQualifier), IrGetBackingField {
constructor(
startOffset: Int,
endOffset: Int,
descriptor: PropertyDescriptor,
receiver: IrExpression?,
operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor, operator, superQualifier) {
this.receiver = receiver
}
override fun getChild(slot: Int): IrElement? =
null
super.getChild(slot)
override fun replaceChild(slot: Int, newChild: IrElement) {
throwNoSuchSlot(slot)
super.replaceChild(slot, newChild)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -59,7 +96,7 @@ class IrGetBackingFieldImpl(
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// no children
receiver?.accept(visitor, data)
}
}
@@ -67,15 +104,19 @@ class IrSetBackingFieldImpl(
startOffset: Int,
endOffset: Int,
descriptor: PropertyDescriptor,
operator: IrOperator? = null
) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type.builtIns.unitType, operator), IrSetBackingField {
operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null
) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type.builtIns.unitType, operator, superQualifier), IrSetBackingField {
constructor(
startOffset: Int,
endOffset: Int,
descriptor: PropertyDescriptor,
receiver: IrExpression?,
value: IrExpression,
operator: IrOperator? = null
) : this(startOffset, endOffset, descriptor, operator) {
operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor, operator, superQualifier) {
this.receiver = receiver
this.value = value
}
@@ -92,12 +133,13 @@ class IrSetBackingFieldImpl(
override fun getChild(slot: Int): IrElement? =
when (slot) {
CHILD_EXPRESSION_SLOT -> value
else -> null
else -> super.getChild(slot)
}
override fun replaceChild(slot: Int, newChild: IrElement) {
when (slot) {
CHILD_EXPRESSION_SLOT -> value = newChild.assertCast()
else -> super.replaceChild(slot, newChild)
}
}
@@ -106,6 +148,7 @@ class IrSetBackingFieldImpl(
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
receiver?.accept(visitor, data)
value.accept(visitor, data)
}
}
@@ -94,6 +94,19 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
}
}
override fun visitGetBackingField(expression: IrGetBackingField, data: String) {
expression.dumpLabeledElementWith(data) {
expression.receiver?.accept(this, "receiver")
}
}
override fun visitSetBackingField(expression: IrSetBackingField, data: String) {
expression.dumpLabeledElementWith(data) {
expression.receiver?.accept(this, "receiver")
expression.value.accept(this, "value")
}
}
override fun visitWhen(expression: IrWhen, data: String) {
expression.dumpLabeledElementWith(data) {
for (i in 0 .. expression.branchesCount - 1) {
@@ -62,8 +62,9 @@ interface IrElementVisitor<out R, in D> {
fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data)
fun visitGetVariable(expression: IrGetVariable, data: D) = visitDeclarationReference(expression, data)
fun visitSetVariable(expression: IrSetVariable, data: D) = visitDeclarationReference(expression, data)
fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitDeclarationReference(expression, data)
fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitDeclarationReference(expression, data)
fun visitBackingFieldReference(expression: IrBackingFieldExpression, data: D) = visitDeclarationReference(expression, data)
fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitBackingFieldReference(expression, data)
fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitBackingFieldReference(expression, data)
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data)
fun visitGeneralCall(expression: IrGeneralCall, data: D) = visitDeclarationReference(expression, data)
fun visitCall(expression: IrCall, data: D) = visitGeneralCall(expression, data)
@@ -129,10 +129,13 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitSetVariable(expression: IrSetVariable) = visitDeclarationReference(expression)
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression)
fun visitGetBackingField(expression: IrGetBackingField) = visitDeclarationReference(expression)
fun visitBackingFieldReference(expression: IrBackingFieldExpression) = visitDeclarationReference(expression)
override fun visitBackingFieldReference(expression: IrBackingFieldExpression, data: Nothing?) = visitBackingFieldReference(expression)
fun visitGetBackingField(expression: IrGetBackingField) = visitBackingFieldReference(expression)
override fun visitGetBackingField(expression: IrGetBackingField, data: Nothing?) = visitGetBackingField(expression)
fun visitSetBackingField(expression: IrSetBackingField) = visitDeclarationReference(expression)
fun visitSetBackingField(expression: IrSetBackingField) = visitBackingFieldReference(expression)
override fun visitSetBackingField(expression: IrSetBackingField, data: Nothing?) = visitSetBackingField(expression)
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver) = visitDeclarationReference(expression)