diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index a90023fafa5..6e5b6424c31 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.PrimitiveType; import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods; +import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.descriptors.*; @@ -511,7 +512,7 @@ public abstract class StackValue { descriptor ); StackValue extensionReceiver = genReceiver(receiver, codegen, resolvedCall, callableMethod, callExtensionReceiver, true); - Type type = CallReceiver.calcType(resolvedCall, dispatchReceiverParameter, extensionReceiverParameter, codegen.typeMapper, callableMethod); + Type type = CallReceiver.calcType(resolvedCall, dispatchReceiverParameter, extensionReceiverParameter, codegen.typeMapper, callableMethod, codegen.getState()); assert type != null : "Could not map receiver type for " + resolvedCall; return new CallReceiver(dispatchReceiver, extensionReceiver, type); } @@ -1328,9 +1329,21 @@ public abstract class StackValue { @Nullable ReceiverParameterDescriptor dispatchReceiver, @Nullable ReceiverParameterDescriptor extensionReceiver, @NotNull JetTypeMapper typeMapper, - @Nullable Callable callableMethod + @Nullable Callable callableMethod, + @NotNull GenerationState state ) { if (extensionReceiver != null) { + CallableDescriptor descriptor = resolvedCall.getCandidateDescriptor(); + + if (descriptor instanceof PropertyDescriptor && + // hackaround: boxing changes behaviour of T.javaClass intrinsic + !(state.getIntrinsics().getIntrinsic((PropertyDescriptor) descriptor) instanceof JavaClassProperty) + ) { + ReceiverParameterDescriptor receiverCandidate = descriptor.getExtensionReceiverParameter(); + assert receiverCandidate != null; + return typeMapper.mapType(receiverCandidate.getType()); + } + return callableMethod != null ? callableMethod.getExtensionReceiverType() : typeMapper.mapType(extensionReceiver.getType()); } else if (dispatchReceiver != null) { diff --git a/compiler/testData/codegen/box/extensionProperties/genericValForPrimitiveType.kt b/compiler/testData/codegen/box/extensionProperties/genericValForPrimitiveType.kt new file mode 100644 index 00000000000..bed63ea51cb --- /dev/null +++ b/compiler/testData/codegen/box/extensionProperties/genericValForPrimitiveType.kt @@ -0,0 +1,39 @@ +val T.valProp: T + get() = this + +class A { + val int: Int = 0 + val long: Long = 0.toLong() + val short: Short = 0.toShort() + val byte: Byte = 0.toByte() + val double: Double = 0.0 + val float: Float = 0.0f + val char: Char = '0' + val bool: Boolean = false + + fun invoke() { + int.valProp + long.valProp + short.valProp + byte.valProp + double.valProp + float.valProp + char.valProp + bool.valProp + } +} + +fun box(): String { + 0.valProp + false.valProp + '0'.valProp + 0.0.valProp + 0.0f.valProp + 0.toByte().valProp + 0.toShort().valProp + 0.toLong().valProp + + A()() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/extensionProperties/genericValMultipleUpperBounds.kt b/compiler/testData/codegen/box/extensionProperties/genericValMultipleUpperBounds.kt new file mode 100644 index 00000000000..7d1f2347a67 --- /dev/null +++ b/compiler/testData/codegen/box/extensionProperties/genericValMultipleUpperBounds.kt @@ -0,0 +1,8 @@ +val T.valProp: T where T : Number, T : Int + get() = this + +fun box(): String { + 0.valProp + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/extensionProperties/genericVarForPrimitiveType.kt b/compiler/testData/codegen/box/extensionProperties/genericVarForPrimitiveType.kt new file mode 100644 index 00000000000..313606e56e0 --- /dev/null +++ b/compiler/testData/codegen/box/extensionProperties/genericVarForPrimitiveType.kt @@ -0,0 +1,40 @@ +var T.varProp: T + get() = this + set(value: T) {} + +class A { + var int: Int = 0 + var long: Long = 0.toLong() + var short: Short = 0.toShort() + var byte: Byte = 0.toByte() + var double: Double = 0.0 + var float: Float = 0.0f + var char: Char = '0' + var bool: Boolean = false + + fun invoke() { + int.varProp = int + long.varProp = long + short.varProp = short + byte.varProp = byte + double.varProp = double + float.varProp = float + char.varProp = char + bool.varProp = bool + } +} + +fun box(): String { + 0.varProp = 0 + false.varProp = false + '0'.varProp = '0' + 0.0.varProp = 0.0 + 0.0f.varProp = 0.0f + 0.toByte().varProp = 0.toByte() + 0.toShort().varProp = 0.toShort() + 0.toLong().varProp = 0.toLong() + + A()() + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index f6c8a2ea330..3a185bfdf97 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3727,6 +3727,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/extensionProperties"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("genericValForPrimitiveType.kt") + public void testGenericValForPrimitiveType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/genericValForPrimitiveType.kt"); + doTest(fileName); + } + + @TestMetadata("genericValMultipleUpperBounds.kt") + public void testGenericValMultipleUpperBounds() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/genericValMultipleUpperBounds.kt"); + doTest(fileName); + } + + @TestMetadata("genericVarForPrimitiveType.kt") + public void testGenericVarForPrimitiveType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/genericVarForPrimitiveType.kt"); + doTest(fileName); + } + @TestMetadata("inClass.kt") public void testInClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/inClass.kt");