Keep track of second receiver type in CallReceiver

#KT-17725 Fixed Target versions 1.1.5
This commit is contained in:
Dmitry Petrov
2017-07-21 10:37:20 +03:00
parent 3f34a97880
commit d0c8af5621
6 changed files with 49 additions and 5 deletions
@@ -29,19 +29,22 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
public class CallReceiver extends StackValue {
private final StackValue dispatchReceiver;
private final StackValue extensionReceiver;
private final Type secondReceiverType;
private CallReceiver(
@NotNull StackValue dispatchReceiver,
@NotNull StackValue extensionReceiver,
@NotNull Type type
@NotNull Type type,
@Nullable Type secondReceiverType
) {
super(type, dispatchReceiver.canHaveSideEffects() || extensionReceiver.canHaveSideEffects());
this.dispatchReceiver = dispatchReceiver;
this.extensionReceiver = extensionReceiver;
this.secondReceiverType = secondReceiverType;
}
public StackValue withoutReceiverArgument() {
return new CallReceiver(dispatchReceiver, none(), type);
return new CallReceiver(dispatchReceiver, none(), type, secondReceiverType);
}
public static StackValue generateCallReceiver(
@@ -57,8 +60,12 @@ public class CallReceiver extends StackValue {
GenerationState state = codegen.getState();
Type type;
Type secondReceiverType = null;
if (extensionReceiverParameter != null) {
type = calcExtensionReceiverType(resolvedCall, extensionReceiverParameter, typeMapper, callableMethod, state);
if (dispatchReceiverParameter != null) {
secondReceiverType = calcDispatchReceiverType(resolvedCall, dispatchReceiverParameter, typeMapper, callableMethod);
}
}
else if (dispatchReceiverParameter != null) {
type = calcDispatchReceiverType(resolvedCall, dispatchReceiverParameter, typeMapper, callableMethod);
@@ -72,7 +79,7 @@ public class CallReceiver extends StackValue {
assert type != null : "Could not map receiver type for " + resolvedCall;
return new CallReceiver(dispatchReceiver, extensionReceiver, type);
return new CallReceiver(dispatchReceiver, extensionReceiver, type, secondReceiverType);
}
private static Type calcDispatchReceiverType(
@@ -135,10 +142,13 @@ public class CallReceiver extends StackValue {
currentExtensionReceiver = StackValue.onStack(currentExtensionReceiver.type);
}
dispatchReceiver.put(hasExtensionReceiver ? dispatchReceiver.type : type, v);
Type dispatchReceiverType = secondReceiverType != null ? secondReceiverType :
hasExtensionReceiver ? dispatchReceiver.type :
type;
dispatchReceiver.put(dispatchReceiverType, v);
currentExtensionReceiver
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiver.type.getSize());
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiverType.getSize());
}
@Override
+10
View File
@@ -0,0 +1,10 @@
class Bob {
fun Bob.bar() = "OK"
}
fun Any.foo() = when(this) {
is Bob -> bar()
else -> throw AssertionError()
}
fun box(): String = Bob().foo()
@@ -17600,6 +17600,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("kt17725.kt")
public void testKt17725() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt");
doTest(fileName);
}
@TestMetadata("kt19058.kt")
public void testKt19058() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19058.kt");
@@ -17600,6 +17600,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("kt17725.kt")
public void testKt17725() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt");
doTest(fileName);
}
@TestMetadata("kt19058.kt")
public void testKt19058() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19058.kt");
@@ -17600,6 +17600,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTest(fileName);
}
@TestMetadata("kt17725.kt")
public void testKt17725() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt");
doTest(fileName);
}
@TestMetadata("kt19058.kt")
public void testKt19058() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19058.kt");
@@ -21506,6 +21506,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("kt17725.kt")
public void testKt17725() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt17725.kt");
doTest(fileName);
}
@TestMetadata("kt19100.kt")
public void testKt19100() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/smartCasts/kt19100.kt");