JVM_IR KT-47398 handle @EnhancedNullability String subject as in 1.0
This commit is contained in:
committed by
teamcityserver
parent
c26d71c4ef
commit
0104b1275f
+12
@@ -42767,12 +42767,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("enhancedNullability.kt")
|
||||||
|
public void testEnhancedNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/enhancedNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("expression.kt")
|
@TestMetadata("expression.kt")
|
||||||
public void testExpression() throws Exception {
|
public void testExpression() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleNullability.kt")
|
||||||
|
public void testFlexibleNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/flexibleNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nullability.kt")
|
@TestMetadata("nullability.kt")
|
||||||
public void testNullability() throws Exception {
|
public void testNullability() throws Exception {
|
||||||
|
|||||||
+15
-4
@@ -9,10 +9,11 @@ import org.jetbrains.kotlin.codegen.`when`.SwitchCodegen.Companion.preferLookupO
|
|||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
import org.jetbrains.kotlin.ir.util.isTrueConst
|
import org.jetbrains.kotlin.ir.util.isTrueConst
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
// TODO: eliminate the temporary variable
|
// TODO: eliminate the temporary variable
|
||||||
class SwitchGenerator(private val expression: IrWhen, private val data: BlockInfo, private val codegen: ExpressionCodegen) {
|
class SwitchGenerator(private val expression: IrWhen, private val data: BlockInfo, private val codegen: ExpressionCodegen) {
|
||||||
@@ -446,9 +447,19 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf
|
|||||||
hashAndSwitchLabels.add(ValueToLabel(key, Label()))
|
hashAndSwitchLabels.add(ValueToLabel(key, Label()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using a switch, the subject string has to be traversed at least twice (hash + comparison * N, where N is #strings hashed into the
|
// Using a switch, the subject string has to be traversed at least twice
|
||||||
// same bucket). The optimization isn't better than an IF cascade when #switch-targets <= 2.
|
// (hash + comparison * N, where N is #strings hashed into the same bucket).
|
||||||
override fun shouldOptimize() = hashAndSwitchLabels.size > 2
|
// The optimization isn't better than an IF cascade when #switch-targets <= 2.
|
||||||
|
//
|
||||||
|
// Generate "optimized" version for @EnhancedNullability subject type
|
||||||
|
// to model 1.0 behavior causing NPE in case of null value.
|
||||||
|
// TODO make 'when' with String subject behavior consistent.
|
||||||
|
// see:
|
||||||
|
// box/when/stringOptimization/enhancedNullability.kt
|
||||||
|
// box/when/stringOptimization/flexibleNullability.kt
|
||||||
|
override fun shouldOptimize() =
|
||||||
|
hashAndSwitchLabels.size > 2 ||
|
||||||
|
subject.type.hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION) && hashAndSwitchLabels.isNotEmpty()
|
||||||
|
|
||||||
override fun genSwitch() {
|
override fun genSwitch() {
|
||||||
with(codegen) {
|
with(codegen) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
// IGNORE_BACKEND: WASM
|
||||||
|
|
||||||
enum class EType {
|
enum class EType {
|
||||||
A
|
A
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
// FILE: enhancedNullability.kt
|
||||||
|
fun testEmpty() {
|
||||||
|
when (J.nullString()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSingle() {
|
||||||
|
try {
|
||||||
|
var q = "other"
|
||||||
|
when (J.nullString()) {
|
||||||
|
"a" -> q = "A"
|
||||||
|
}
|
||||||
|
throw Exception("Should throw NPE, got '$q'")
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testElseOnly() {
|
||||||
|
var q = "other"
|
||||||
|
when (J.nullString()) {
|
||||||
|
else -> q = "A"
|
||||||
|
}
|
||||||
|
if (q != "A") {
|
||||||
|
throw Exception("Expected: 'A', got '$q'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSmall() {
|
||||||
|
try {
|
||||||
|
val q = when (J.nullString()) {
|
||||||
|
"a" -> "A"
|
||||||
|
else -> "other"
|
||||||
|
}
|
||||||
|
throw Exception("Should throw NPE, got '$q'")
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testBigger() {
|
||||||
|
try {
|
||||||
|
val q = when (J.nullString()) {
|
||||||
|
"a" -> "A"
|
||||||
|
"b" -> "B"
|
||||||
|
"c" -> "C"
|
||||||
|
"d" -> "D"
|
||||||
|
"e" -> "E"
|
||||||
|
"f" -> "F"
|
||||||
|
"g" -> "G"
|
||||||
|
"h" -> "H"
|
||||||
|
else -> "other"
|
||||||
|
}
|
||||||
|
throw Exception("Should throw NPE, got '$q'")
|
||||||
|
} catch (e: NullPointerException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
testEmpty()
|
||||||
|
testSingle()
|
||||||
|
testElseOnly()
|
||||||
|
testSmall()
|
||||||
|
testBigger()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class J {
|
||||||
|
public static @NotNull String nullString() { return null; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
// FILE: flexibleNullability.kt
|
||||||
|
fun testEmpty() {
|
||||||
|
when (J.nullString()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSingle() {
|
||||||
|
var q = "other"
|
||||||
|
when (J.nullString()) {
|
||||||
|
"a" -> q = "A"
|
||||||
|
}
|
||||||
|
if (q != "other") {
|
||||||
|
throw Exception("Expected 'other', got '$q'")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testElseOnly() {
|
||||||
|
var q = "other"
|
||||||
|
when (J.nullString()) {
|
||||||
|
else -> q = "A"
|
||||||
|
}
|
||||||
|
if (q != "A") {
|
||||||
|
throw Exception("Expected: 'A', got '$q'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testSmall() {
|
||||||
|
val q = when (J.nullString()) {
|
||||||
|
"a" -> "A"
|
||||||
|
else -> "other"
|
||||||
|
}
|
||||||
|
if (q != "other") {
|
||||||
|
throw Exception("Expected 'other', got '$q'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testBigger() {
|
||||||
|
val q = when (J.nullString()) {
|
||||||
|
"a" -> "A"
|
||||||
|
"b" -> "B"
|
||||||
|
"c" -> "C"
|
||||||
|
"d" -> "D"
|
||||||
|
"e" -> "E"
|
||||||
|
"f" -> "F"
|
||||||
|
"g" -> "G"
|
||||||
|
"h" -> "H"
|
||||||
|
else -> "other"
|
||||||
|
}
|
||||||
|
if (q != "other") {
|
||||||
|
throw Exception("Expected 'other', got '$q'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
testEmpty()
|
||||||
|
testSingle()
|
||||||
|
testElseOnly()
|
||||||
|
testSmall()
|
||||||
|
testBigger()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: J.java
|
||||||
|
public class J {
|
||||||
|
public static String nullString() { return null; }
|
||||||
|
}
|
||||||
+12
@@ -42725,12 +42725,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("enhancedNullability.kt")
|
||||||
|
public void testEnhancedNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/enhancedNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("expression.kt")
|
@TestMetadata("expression.kt")
|
||||||
public void testExpression() throws Exception {
|
public void testExpression() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleNullability.kt")
|
||||||
|
public void testFlexibleNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/flexibleNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nullability.kt")
|
@TestMetadata("nullability.kt")
|
||||||
public void testNullability() throws Exception {
|
public void testNullability() throws Exception {
|
||||||
|
|||||||
+12
@@ -42767,12 +42767,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("enhancedNullability.kt")
|
||||||
|
public void testEnhancedNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/enhancedNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("expression.kt")
|
@TestMetadata("expression.kt")
|
||||||
public void testExpression() throws Exception {
|
public void testExpression() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleNullability.kt")
|
||||||
|
public void testFlexibleNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/flexibleNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nullability.kt")
|
@TestMetadata("nullability.kt")
|
||||||
public void testNullability() throws Exception {
|
public void testNullability() throws Exception {
|
||||||
|
|||||||
+10
@@ -34445,11 +34445,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/duplicatingItemsSameHashCode3.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("enhancedNullability.kt")
|
||||||
|
public void testEnhancedNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/enhancedNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("expression.kt")
|
@TestMetadata("expression.kt")
|
||||||
public void testExpression() throws Exception {
|
public void testExpression() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/expression.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("flexibleNullability.kt")
|
||||||
|
public void testFlexibleNullability() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/when/stringOptimization/flexibleNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nullability.kt")
|
@TestMetadata("nullability.kt")
|
||||||
public void testNullability() throws Exception {
|
public void testNullability() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/when/stringOptimization/nullability.kt");
|
runTest("compiler/testData/codegen/box/when/stringOptimization/nullability.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user