Fix safe call code generation for ranges.
This commit is contained in:
@@ -45,8 +45,7 @@ public interface Callable {
|
||||
}
|
||||
}
|
||||
|
||||
public fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
||||
|
||||
public fun afterReceiverGeneration(v: InstructionAdapter) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.intellij.util.containers.Stack;
|
||||
import kotlin.CollectionsKt;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
@@ -2394,11 +2393,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@NotNull CallGenerator callGenerator,
|
||||
@NotNull ArgumentGenerator argumentGenerator
|
||||
) {
|
||||
callableMethod.beforeParameterGeneration(v, null);
|
||||
|
||||
if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
|
||||
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
|
||||
receiver.put(receiver.type, v);
|
||||
callableMethod.afterReceiverGeneration(v);
|
||||
}
|
||||
|
||||
callGenerator.putHiddenParams();
|
||||
|
||||
@@ -44,10 +44,19 @@ public class RangeTo : IntrinsicMethod() {
|
||||
nullOr(method.dispatchReceiverType, argType),
|
||||
nullOr(method.extensionReceiverType, argType)
|
||||
) {
|
||||
override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
||||
override fun afterReceiverGeneration(v: InstructionAdapter) {
|
||||
v.anew(returnType)
|
||||
v.dup()
|
||||
value?.moveToTopOfStack(value.type, v, 2)
|
||||
when (argType.size) {
|
||||
1 -> {
|
||||
v.dupX1()
|
||||
v.swap()
|
||||
}
|
||||
2 -> {
|
||||
v.dup()
|
||||
v.dup2X2()
|
||||
v.pop2()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
fun charRange(x: Char?, y: Char) = x?.rangeTo(y)
|
||||
fun byteRange(x: Byte?, y: Byte) = x?.rangeTo(y)
|
||||
fun shortRange(x: Short?, y: Short) = x?.rangeTo(y)
|
||||
fun intRange(x: Int?, y: Int) = x?.rangeTo(y)
|
||||
fun longRange(x: Long?, y: Long) = x?.rangeTo(y)
|
||||
fun floatRange(x: Float?, y: Float) = x?.rangeTo(y)
|
||||
fun dougleRange(x: Double?, y: Double) = x?.rangeTo(y)
|
||||
|
||||
inline fun <reified T, R> testSafeRange(x: T, y: T, expectStr: String, safeRange: (T?, T) -> R?) {
|
||||
val rNull = safeRange(null, y)
|
||||
assert (rNull == null) { "${T::class.simpleName}: Expected: null, got $rNull" }
|
||||
|
||||
val rxy = safeRange(x, y)
|
||||
assert (rxy?.toString() == expectStr) { "${T::class.simpleName}: Expected: $expectStr, got $rxy" }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
testSafeRange('0', '1', "0..1", ::charRange)
|
||||
testSafeRange(0, 1, "0..1", ::byteRange)
|
||||
testSafeRange(0, 1, "0..1", ::shortRange)
|
||||
testSafeRange(0, 1, "0..1", ::intRange)
|
||||
testSafeRange(0L, 1L, "0..1", ::longRange)
|
||||
testSafeRange(0.0f, 1.0f, "0.0..1.0", ::floatRange)
|
||||
testSafeRange(0.0, 1.0, "0.0..1.0", ::dougleRange)
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -2707,6 +2707,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("safeCallRangeTo.kt")
|
||||
public void testSafeCallRangeTo() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/ranges/safeCallRangeTo.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/ranges/expression")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user