Box primitive types in position of generic receiver
#KT-9469 fixed
This commit is contained in:
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
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.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
@@ -511,7 +512,7 @@ public abstract class StackValue {
|
|||||||
descriptor
|
descriptor
|
||||||
);
|
);
|
||||||
StackValue extensionReceiver = genReceiver(receiver, codegen, resolvedCall, callableMethod, callExtensionReceiver, true);
|
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;
|
assert type != null : "Could not map receiver type for " + resolvedCall;
|
||||||
return new CallReceiver(dispatchReceiver, extensionReceiver, type);
|
return new CallReceiver(dispatchReceiver, extensionReceiver, type);
|
||||||
}
|
}
|
||||||
@@ -1328,9 +1329,21 @@ public abstract class StackValue {
|
|||||||
@Nullable ReceiverParameterDescriptor dispatchReceiver,
|
@Nullable ReceiverParameterDescriptor dispatchReceiver,
|
||||||
@Nullable ReceiverParameterDescriptor extensionReceiver,
|
@Nullable ReceiverParameterDescriptor extensionReceiver,
|
||||||
@NotNull JetTypeMapper typeMapper,
|
@NotNull JetTypeMapper typeMapper,
|
||||||
@Nullable Callable callableMethod
|
@Nullable Callable callableMethod,
|
||||||
|
@NotNull GenerationState state
|
||||||
) {
|
) {
|
||||||
if (extensionReceiver != null) {
|
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());
|
return callableMethod != null ? callableMethod.getExtensionReceiverType() : typeMapper.mapType(extensionReceiver.getType());
|
||||||
}
|
}
|
||||||
else if (dispatchReceiver != null) {
|
else if (dispatchReceiver != null) {
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
val <T> 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"
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
val <T> T.valProp: T where T : Number, T : Int
|
||||||
|
get() = this
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
0.valProp
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
var <T> 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"
|
||||||
|
}
|
||||||
+18
@@ -3727,6 +3727,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/extensionProperties"), Pattern.compile("^(.+)\\.kt$"), true);
|
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")
|
@TestMetadata("inClass.kt")
|
||||||
public void testInClass() throws Exception {
|
public void testInClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/inClass.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/extensionProperties/inClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user