KT-16904 Wrong IR when applying some operators to superclass properties in constructor

Use property accessors for assignment generation for inherited properties in constructor.
This commit is contained in:
Dmitry Petrov
2017-03-17 14:24:11 +03:00
parent 5405c81106
commit d05de88e3e
4 changed files with 120 additions and 15 deletions
@@ -131,27 +131,29 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
origin: IrStatementOrigin,
ktLeft: KtExpression,
resolvedCall: ResolvedCall<*>
): AssignmentReceiver {
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
val thisClass = getThisClass()
val irThis = IrGetValueImpl(ktLeft.startOffset, ktLeft.endOffset, thisClass.thisAsReceiverParameter)
return BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor,
RematerializableValue(irThis), null)
}
): AssignmentReceiver =
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
val thisClass = getThisClass()
val irThis = IrGetValueImpl(ktLeft.startOffset, ktLeft.endOffset, thisClass.thisAsReceiverParameter)
val propertyReceiver = statementGenerator.generateCallReceiver(
ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
isSafe = resolvedCall.call.isSafeCall(),
isAssignmentReceiver = true)
BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor,
RematerializableValue(irThis), null)
}
else {
val propertyReceiver = statementGenerator.generateCallReceiver(
ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
isSafe = resolvedCall.call.isSafeCall(),
isAssignmentReceiver = true)
val superQualifier = getSuperQualifier(resolvedCall)
val superQualifier = getSuperQualifier(resolvedCall)
return SimplePropertyLValue(context, scope, ktLeft.startOffset, ktLeft.endOffset, origin, descriptor,
getTypeArguments(resolvedCall), propertyReceiver, superQualifier)
}
SimplePropertyLValue(context, scope, ktLeft.startOffset, ktLeft.endOffset, origin, descriptor,
getTypeArguments(resolvedCall), propertyReceiver, superQualifier)
}
private fun isValInitializationInConstructor(descriptor: PropertyDescriptor, resolvedCall: ResolvedCall<*>): Boolean =
!descriptor.isVar &&
descriptor.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
statementGenerator.scopeOwner.let { it is ConstructorDescriptor || it is ClassDescriptor } &&
resolvedCall.dispatchReceiver is ThisClassReceiver