JVM_IR KT-24258 fix NPE message for delegated properties

This commit is contained in:
Dmitry Petrov
2020-12-23 17:19:02 +03:00
committed by TeamCityServer
parent ad8bed078f
commit 4e261cc358
11 changed files with 175 additions and 23 deletions
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.isInlined
import org.jetbrains.kotlin.ir.util.render
@@ -148,7 +147,7 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
IrTypeOperator.IMPLICIT_NOTNULL -> {
val owner = scope.scopeOwnerSymbol.owner
val source = if (owner is IrFunction && owner.origin == IrDeclarationOrigin.DELEGATED_MEMBER) {
val source = if (owner is IrFunction && owner.isDelegated()) {
"${owner.name.asString()}(...)"
} else {
val (startOffset, endOffset) = expression.extents()
@@ -173,6 +172,10 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
}
}
private fun IrFunction.isDelegated() =
origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR ||
origin == IrDeclarationOrigin.DELEGATED_MEMBER
private fun IrElement.extents(): Pair<Int, Int> {
var startOffset = UNDEFINED_OFFSET
var endOffset = UNDEFINED_OFFSET
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irReturn
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrLocalDelegatedPropertyDelegateDescr
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
@@ -391,21 +393,17 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
irPropertyReference: IrCallableReference<*>
): IrBody =
with(createBodyGenerator(irGetter.symbol)) {
val startOffset = ktDelegate.startOffsetSkippingComments
val endOffset = ktDelegate.endOffset
val ktDelegateExpression = ktDelegate.expression!!
val startOffset = ktDelegateExpression.startOffsetSkippingComments
val endOffset = ktDelegateExpression.endOffset
irBlockBody(startOffset, endOffset) {
val statementGenerator = createStatementGenerator()
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
updateNullThisRefValue(conventionMethodCall)
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
+irReturn(
CallGenerator(statementGenerator).generateCall(
startOffset,
endOffset,
conventionMethodCall
)
)
+irReturn(CallGenerator(statementGenerator).generateCall(startOffset, endOffset, conventionMethodCall))
}
}
@@ -415,18 +413,29 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
setterDescriptor: VariableAccessorDescriptor,
delegateReceiverValue: IntermediateValue,
irPropertyReference: IrCallableReference<*>
): IrBody = with(createBodyGenerator(irSetter.symbol)) {
val startOffset = ktDelegate.startOffsetSkippingComments
val endOffset = ktDelegate.endOffset
irBlockBody(startOffset, endOffset) {
val statementGenerator = createStatementGenerator()
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
val irSetterParameter = irSetter.valueParameters[0]
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(irSetterParameter.type, irSetterParameter.symbol)
+irReturn(CallGenerator(statementGenerator).generateCall(startOffset, endOffset, conventionMethodCall))
): IrBody =
with(createBodyGenerator(irSetter.symbol)) {
val ktDelegateExpression = ktDelegate.expression!!
val startOffset = ktDelegateExpression.startOffsetSkippingComments
val endOffset = ktDelegateExpression.endOffset
irBlockBody(startOffset, endOffset) {
val statementGenerator = createStatementGenerator()
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
updateNullThisRefValue(conventionMethodCall)
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
val irSetterParameter = irSetter.valueParameters[0]
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(irSetterParameter)
+irReturn(CallGenerator(statementGenerator).generateCall(startOffset, endOffset, conventionMethodCall))
}
}
private fun updateNullThisRefValue(conventionMethodCall: CallBuilder) {
val arg0 = conventionMethodCall.irValueArgumentsByIndex[0]
if (arg0 is IrConstImpl<*> && arg0.kind == IrConstKind.Null) {
conventionMethodCall.irValueArgumentsByIndex[0] =
IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.nothingNType)
}
}
}