diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index 555c5f4c26a..6da5a034902 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -34,8 +34,10 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.StringValue; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.types.Flexibility; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.lang.types.TypesPackage; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.org.objectweb.asm.*; @@ -184,6 +186,14 @@ public abstract class AnnotationCodegen { return; } + if (TypesPackage.isFlexible(type)) { + // A flexible type whose lower bound in not-null and upper bound is nullable, should not be annotated + Flexibility flexibility = TypesPackage.flexibility(type); + if (!TypeUtils.isNullableType(flexibility.getLowerBound()) && TypeUtils.isNullableType(flexibility.getUpperBound())) { + return; + } + } + boolean isNullableType = TypeUtils.isNullableType(type); Class annotationClass = isNullableType ? Nullable.class : NotNull.class; diff --git a/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.java b/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.java new file mode 100644 index 00000000000..52a98c248e8 --- /dev/null +++ b/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.java @@ -0,0 +1,11 @@ +public final class PlatformTypes implements kotlin.jvm.internal.KObject { + public final java.lang.String simplyPlatform() { /* compiled code */ } + + @org.jetbrains.annotations.Nullable + public final java.util.List bothNullable() { /* compiled code */ } + + @org.jetbrains.annotations.NotNull + public final java.util.List bothNotNull() { /* compiled code */ } + + public PlatformTypes() { /* compiled code */ } +} diff --git a/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.kt b/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.kt new file mode 100644 index 00000000000..31d49c2199f --- /dev/null +++ b/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.kt @@ -0,0 +1,9 @@ +// PlatformTypes + +import java.util.Collections + +class PlatformTypes { + fun simplyPlatform() = Collections.singletonList("")[0] + fun bothNullable() = Collections.emptyList() ?: null + fun bothNotNull() = Collections.emptyList()!! +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTestGenerated.java b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTestGenerated.java index 7b49f0f80dd..cfe42fd6e19 100644 --- a/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/asJava/KotlinLightClassTestGenerated.java @@ -114,6 +114,12 @@ public class KotlinLightClassTestGenerated extends AbstractKotlinLightClassTest doTest(fileName); } + @TestMetadata("PlatformTypes.kt") + public void testPlatformTypes() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/nullabilityAnnotations/PlatformTypes.kt"); + doTest(fileName); + } + @TestMetadata("Primitives.kt") public void testPrimitives() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/nullabilityAnnotations/Primitives.kt");