From 3291cf7a6e1b5fcd0f452675f6b5d58db02a4a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Tue, 2 Jun 2020 12:02:29 +0200 Subject: [PATCH] JVM IR: Mark lateinit fields as NotNull This is needed for compatibility with the JVM backend. --- .../backend/jvm/codegen/AnnotationCodegen.kt | 16 ++++++++++------ .../codegen/bytecodeListing/lateInitNotNull.kt | 5 +++++ .../codegen/bytecodeListing/lateInitNotNull.txt | 7 +++++++ .../codegen/BytecodeListingTestGenerated.java | 5 +++++ .../ir/IrBytecodeListingTestGenerated.java | 5 +++++ 5 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt create mode 100644 compiler/testData/codegen/bytecodeListing/lateInitNotNull.txt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt index 4e4ee1fb36c..85f877110ac 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/AnnotationCodegen.kt @@ -33,19 +33,17 @@ import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.synthetic.isVisibleOutside import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext import org.jetbrains.kotlin.types.isNullabilityFlexible import org.jetbrains.kotlin.types.model.KotlinTypeMarker -import org.jetbrains.org.objectweb.asm.* +import org.jetbrains.org.objectweb.asm.AnnotationVisitor +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.TypePath import java.lang.annotation.RetentionPolicy abstract class AnnotationCodegen( @@ -139,8 +137,14 @@ abstract class AnnotationCodegen( val type = when (declaration) { is IrFunction -> declaration.returnType - is IrField -> declaration.type is IrValueDeclaration -> declaration.type + is IrField -> + if (declaration.correspondingPropertySymbol?.owner?.isLateinit == true) { + // Lateinit fields are nullable, but should be marked as NotNull to match the JVM backend. + declaration.type.makeNotNull() + } else { + declaration.type + } else -> return } diff --git a/compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt b/compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt new file mode 100644 index 00000000000..1fdef1fd787 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt @@ -0,0 +1,5 @@ +// Test to ensure that we mark the backing field of a lateinit property +// as NotNull, even though the field is nullable in the JVM IR backend. +class A { + lateinit var x: A +} diff --git a/compiler/testData/codegen/bytecodeListing/lateInitNotNull.txt b/compiler/testData/codegen/bytecodeListing/lateInitNotNull.txt new file mode 100644 index 00000000000..630374a13a9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/lateInitNotNull.txt @@ -0,0 +1,7 @@ +@kotlin.Metadata +public final class A { + public @org.jetbrains.annotations.NotNull field x: A + public method (): void + public final @org.jetbrains.annotations.NotNull method getX(): A + public final method setX(@org.jetbrains.annotations.NotNull p0: A): void +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 6dbe086f617..cebfa826cf6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -74,6 +74,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.kt"); } + @TestMetadata("lateInitNotNull.kt") + public void testLateInitNotNull() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt"); + } + @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index 115d9edd9bc..9e8fcbe7642 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -74,6 +74,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.kt"); } + @TestMetadata("lateInitNotNull.kt") + public void testLateInitNotNull() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt"); + } + @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt");