JVM_IR handle @EnhancedNullability types in null check simplification

This commit is contained in:
Dmitry Petrov
2021-09-29 15:30:39 +03:00
committed by teamcityserver
parent cc885f9b24
commit 86b3ea09c2
7 changed files with 85 additions and 7 deletions
@@ -39746,6 +39746,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/safeCall/safeCallOnLong.kt");
}
@Test
@TestMetadata("safeCallSimplificationEnhancedNullabilityType.kt")
public void testSafeCallSimplificationEnhancedNullabilityType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationEnhancedNullabilityType.kt");
}
@Test
@TestMetadata("safeCallSimplificationFlexibleType.kt")
public void testSafeCallSimplificationFlexibleType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationFlexibleType.kt");
}
@Test
@TestMetadata("safeCallWithElvisFolding.kt")
public void testSafeCallWithElvisFolding() throws Exception {
@@ -8,18 +8,18 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
val jvmSafeCallFoldingPhase = makeIrFilePhase(
@@ -119,14 +119,17 @@ class JvmSafeCallChainFoldingLowering(val context: JvmBackendContext) : FileLowe
IrConstImpl.boolean(startOffset, endOffset, context.irBuiltIns.booleanType, false)
private fun irValNotNull(startOffset: Int, endOffset: Int, irVariable: IrVariable): IrExpression =
if (irVariable.type.isNullable())
if (irVariable.type.isJvmNullable())
IrGetValueImpl(startOffset, endOffset, irVariable.symbol).irEqEqNull().irNot()
else
irTrue(startOffset, endOffset)
private fun IrType.isJvmNullable(): Boolean =
isNullable() || hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)
private fun IrType.isJvmPrimitive(): Boolean =
// TODO get rid of type mapper (take care of '@EnhancedNullability', maybe some other stuff).
AsmUtil.isPrimitive(context.typeMapper.mapType(this))
(isBoolean() || isByte() || isShort() || isInt() || isLong() || isChar() || isFloat() || isDouble()) &&
!hasAnnotation(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)
private inner class Transformer : IrElementTransformerVoid() {
override fun visitBlock(expression: IrBlock): IrExpression {
@@ -393,7 +396,7 @@ class JvmSafeCallChainFoldingLowering(val context: JvmBackendContext) : FileLowe
if (this.origin != JvmLoweredStatementOrigin.FOLDED_SAFE_CALL) return false
val innerWhen = this.statements[0] as? IrWhen ?: return false
val safeCallResult = innerWhen.branches[0].result
return !safeCallResult.type.isNullable()
return !safeCallResult.type.isJvmNullable()
}
override fun visitCall(expression: IrCall): IrExpression {
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// FILE: safeCallSimplificationEnhancedNullabilityType.kt
fun String.zap() = "failed"
fun box() =
J.nullString()?.zap()
?: "OK"
// FILE: J.java
import org.jetbrains.annotations.NotNull;
public class J {
@NotNull
public static String nullString() { return null; }
}
@@ -0,0 +1,13 @@
// TARGET_BACKEND: JVM
// FILE: safeCallSimplificationFlexibleType.kt
fun String.zap() = "failed"
fun box() =
J.nullString()?.zap()
?: "OK"
// FILE: J.java
public class J {
public static String nullString() { return null; }
}
@@ -39590,6 +39590,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/safeCall/safeCallOnLong.kt");
}
@Test
@TestMetadata("safeCallSimplificationEnhancedNullabilityType.kt")
public void testSafeCallSimplificationEnhancedNullabilityType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationEnhancedNullabilityType.kt");
}
@Test
@TestMetadata("safeCallSimplificationFlexibleType.kt")
public void testSafeCallSimplificationFlexibleType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationFlexibleType.kt");
}
@Test
@TestMetadata("safeCallWithElvisFolding.kt")
public void testSafeCallWithElvisFolding() throws Exception {
@@ -39746,6 +39746,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/safeCall/safeCallOnLong.kt");
}
@Test
@TestMetadata("safeCallSimplificationEnhancedNullabilityType.kt")
public void testSafeCallSimplificationEnhancedNullabilityType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationEnhancedNullabilityType.kt");
}
@Test
@TestMetadata("safeCallSimplificationFlexibleType.kt")
public void testSafeCallSimplificationFlexibleType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationFlexibleType.kt");
}
@Test
@TestMetadata("safeCallWithElvisFolding.kt")
public void testSafeCallWithElvisFolding() throws Exception {
@@ -31688,6 +31688,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/safeCall/safeCallOnLong.kt");
}
@TestMetadata("safeCallSimplificationEnhancedNullabilityType.kt")
public void testSafeCallSimplificationEnhancedNullabilityType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationEnhancedNullabilityType.kt");
}
@TestMetadata("safeCallSimplificationFlexibleType.kt")
public void testSafeCallSimplificationFlexibleType() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallSimplificationFlexibleType.kt");
}
@TestMetadata("safeCallWithElvisFolding.kt")
public void testSafeCallWithElvisFolding() throws Exception {
runTest("compiler/testData/codegen/box/safeCall/safeCallWithElvisFolding.kt");