[PSI2IR] Generate safe calls correctly
This commit is contained in:
committed by
TeamCityServer
parent
229a009828
commit
a760865767
+6
@@ -16247,6 +16247,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/plusMatrix.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/plusMatrix.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("propertyCompoundAssignment.kt")
|
||||||
|
public void testPropertyCompoundAssignment() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/propertyCompoundAssignment.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simpleCall.kt")
|
@TestMetadata("simpleCall.kt")
|
||||||
public void testSimpleCall() throws Exception {
|
public void testSimpleCall() throws Exception {
|
||||||
|
|||||||
+1
-2
@@ -31,7 +31,6 @@ class SafeCallReceiver(
|
|||||||
val startOffset: Int,
|
val startOffset: Int,
|
||||||
val endOffset: Int,
|
val endOffset: Int,
|
||||||
val extensionReceiver: IntermediateValue?,
|
val extensionReceiver: IntermediateValue?,
|
||||||
// TODO: Use context receivers
|
|
||||||
val contextReceivers: List<IntermediateValue>,
|
val contextReceivers: List<IntermediateValue>,
|
||||||
val dispatchReceiver: IntermediateValue?,
|
val dispatchReceiver: IntermediateValue?,
|
||||||
val isStatement: Boolean
|
val isStatement: Boolean
|
||||||
@@ -51,7 +50,7 @@ class SafeCallReceiver(
|
|||||||
extensionReceiverValue = null
|
extensionReceiverValue = null
|
||||||
}
|
}
|
||||||
|
|
||||||
val irResult = withDispatchAndExtensionAndContextReceivers(dispatchReceiverValue, extensionReceiverValue, emptyList())
|
val irResult = withDispatchAndExtensionAndContextReceivers(dispatchReceiverValue, extensionReceiverValue, contextReceivers)
|
||||||
|
|
||||||
val resultType = if (isStatement) generator.context.irBuiltIns.unitType else irResult.type.makeNullable()
|
val resultType = if (isStatement) generator.context.irBuiltIns.unitType else irResult.type.makeNullable()
|
||||||
|
|
||||||
|
|||||||
Vendored
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
|
class LoggingCounter {
|
||||||
|
var operationCounter = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
context(LoggingCounter)
|
||||||
|
var p: Int
|
||||||
|
get(): Int {
|
||||||
|
operationCounter++
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
set(value: Int) {
|
||||||
|
operationCounter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() = A()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val loggingCounter = LoggingCounter()
|
||||||
|
with(loggingCounter) {
|
||||||
|
foo().p += 1
|
||||||
|
foo().p = 1
|
||||||
|
foo()?.p = 1
|
||||||
|
foo().p
|
||||||
|
}
|
||||||
|
val operationsTotal = loggingCounter.operationCounter
|
||||||
|
return if (operationsTotal == 5) "OK" else "$operationsTotal"
|
||||||
|
}
|
||||||
+6
@@ -16247,6 +16247,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/plusMatrix.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/plusMatrix.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("propertyCompoundAssignment.kt")
|
||||||
|
public void testPropertyCompoundAssignment() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/propertyCompoundAssignment.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simpleCall.kt")
|
@TestMetadata("simpleCall.kt")
|
||||||
public void testSimpleCall() throws Exception {
|
public void testSimpleCall() throws Exception {
|
||||||
|
|||||||
+16
-1
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ContextReceiver;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||||
import org.jetbrains.kotlin.types.*;
|
import org.jetbrains.kotlin.types.*;
|
||||||
import org.jetbrains.kotlin.utils.SmartSet;
|
import org.jetbrains.kotlin.utils.SmartSet;
|
||||||
@@ -444,7 +445,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
|||||||
|
|
||||||
List<ReceiverParameterDescriptor> substitutedContextReceivers = new ArrayList<ReceiverParameterDescriptor>();
|
List<ReceiverParameterDescriptor> substitutedContextReceivers = new ArrayList<ReceiverParameterDescriptor>();
|
||||||
for (ReceiverParameterDescriptor contextReceiverParameter: contextReceiverParameters) {
|
for (ReceiverParameterDescriptor contextReceiverParameter: contextReceiverParameters) {
|
||||||
ReceiverParameterDescriptor substitutedContextReceiver = substituteParameterDescriptor(substitutor, substitutedDescriptor,
|
ReceiverParameterDescriptor substitutedContextReceiver = substituteContextParameterDescriptor(substitutor, substitutedDescriptor,
|
||||||
contextReceiverParameter);
|
contextReceiverParameter);
|
||||||
if (substitutedContextReceiver != null) {
|
if (substitutedContextReceiver != null) {
|
||||||
substitutedContextReceivers.add(substitutedContextReceiver);
|
substitutedContextReceivers.add(substitutedContextReceiver);
|
||||||
@@ -541,6 +542,20 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ReceiverParameterDescriptor substituteContextParameterDescriptor(
|
||||||
|
TypeSubstitutor substitutor,
|
||||||
|
PropertyDescriptor substitutedPropertyDescriptor,
|
||||||
|
ReceiverParameterDescriptor receiverParameterDescriptor
|
||||||
|
) {
|
||||||
|
KotlinType substitutedType = substitutor.substitute(receiverParameterDescriptor.getType(), Variance.IN_VARIANCE);
|
||||||
|
if (substitutedType == null) return null;
|
||||||
|
return new ReceiverParameterDescriptorImpl(
|
||||||
|
substitutedPropertyDescriptor,
|
||||||
|
new ContextReceiver(substitutedPropertyDescriptor, substitutedType, receiverParameterDescriptor.getValue()),
|
||||||
|
receiverParameterDescriptor.getAnnotations()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private static FunctionDescriptor getSubstitutedInitialSignatureDescriptor(
|
private static FunctionDescriptor getSubstitutedInitialSignatureDescriptor(
|
||||||
@NotNull TypeSubstitutor substitutor,
|
@NotNull TypeSubstitutor substitutor,
|
||||||
@NotNull PropertyAccessorDescriptor accessorDescriptor
|
@NotNull PropertyAccessorDescriptor accessorDescriptor
|
||||||
|
|||||||
+6
@@ -16434,6 +16434,12 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/plusMatrix.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/plusMatrix.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("propertyCompoundAssignment.kt")
|
||||||
|
public void testPropertyCompoundAssignment() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/propertyCompoundAssignment.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("simpleCall.kt")
|
@TestMetadata("simpleCall.kt")
|
||||||
public void testSimpleCall() throws Exception {
|
public void testSimpleCall() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user