From 8a66919a5c058c7ea54351db3aeefce6604e81b0 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 6 Sep 2017 13:57:05 +0300 Subject: [PATCH] Support @NonNull(when = NEVER) nullability annotation #KT-20131 Fixed --- .../tests/jsr305NonNullNever.kt | 41 +++++++++++++++++++ .../tests/jsr305NonNullNever.txt | 19 +++++++++ .../jsr305Strange.txt | 2 +- .../tests/jsr305Strange.txt | 2 +- ...sNoAnnotationInClasspathTestGenerated.java | 6 +++ ...pathWithFastClassReadingTestGenerated.java | 6 +++ .../ForeignAnnotationsTestGenerated.java | 6 +++ .../JavacForeignAnnotationsTestGenerated.java | 6 +++ .../typeEnhancement/signatureEnhancement.kt | 2 +- 9 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.txt diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt b/compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt new file mode 100644 index 00000000000..a9b585a3f0e --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt @@ -0,0 +1,41 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER +// FILE: MyNullable.java +import javax.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +@Documented +@TypeQualifierNickname +@Nonnull(when = When.NEVER) +@Retention(RetentionPolicy.RUNTIME) +public @interface MyNullable { + +} + +// FILE: A.java + +import javax.annotation.*; +import javax.annotation.meta.When; + +public class A { + @Nonnull(when = When.NEVER) public String field = null; + + @MyNullable + public String foo(@Nonnull(when = When.NEVER) String x, @MyNullable CharSequence y) { + return ""; + } +} +// FILE: main.kt + +fun main(a: A) { + a.foo("", null)?.length + a.foo("", null).length + a.foo(null, "").length + + a.field?.length + a.field.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.txt b/compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.txt new file mode 100644 index 00000000000..6b5bc77a4ea --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.txt @@ -0,0 +1,19 @@ +package + +public fun main(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + @javax.annotation.Nonnull(when = When.NEVER) public final var field: kotlin.String? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyNullable public open fun foo(/*0*/ @javax.annotation.Nonnull(when = When.NEVER) x: kotlin.String?, /*1*/ @MyNullable y: kotlin.CharSequence?): kotlin.String? + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.MustBeDocumented @javax.annotation.meta.TypeQualifierNickname @javax.annotation.Nonnull(when = When.NEVER) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyNullable : kotlin.Annotation { + public constructor MyNullable() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/jsr305Strange.txt b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/jsr305Strange.txt index 25bdaa38663..988a1586884 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/jsr305Strange.txt +++ b/compiler/testData/foreignAnnotations/tests/jsr305NullabilityWarnings/jsr305Strange.txt @@ -7,7 +7,7 @@ public open class A { @javax.annotation.Nonnull(when = When.UNKNOWN) public final var field: kotlin.String! @javax.annotation.Nonnull public open fun bar(): kotlin.String public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - @javax.annotation.Nonnull(when = When.MAYBE) public open fun foo(/*0*/ @javax.annotation.Nonnull(when = When.ALWAYS) x: kotlin.String, /*1*/ @javax.annotation.Nonnull(when = When.NEVER) y: kotlin.CharSequence!): kotlin.String? + @javax.annotation.Nonnull(when = When.MAYBE) public open fun foo(/*0*/ @javax.annotation.Nonnull(when = When.ALWAYS) x: kotlin.String, /*1*/ @javax.annotation.Nonnull(when = When.NEVER) y: kotlin.CharSequence?): kotlin.String? public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/testData/foreignAnnotations/tests/jsr305Strange.txt b/compiler/testData/foreignAnnotations/tests/jsr305Strange.txt index 25bdaa38663..988a1586884 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305Strange.txt +++ b/compiler/testData/foreignAnnotations/tests/jsr305Strange.txt @@ -7,7 +7,7 @@ public open class A { @javax.annotation.Nonnull(when = When.UNKNOWN) public final var field: kotlin.String! @javax.annotation.Nonnull public open fun bar(): kotlin.String public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - @javax.annotation.Nonnull(when = When.MAYBE) public open fun foo(/*0*/ @javax.annotation.Nonnull(when = When.ALWAYS) x: kotlin.String, /*1*/ @javax.annotation.Nonnull(when = When.NEVER) y: kotlin.CharSequence!): kotlin.String? + @javax.annotation.Nonnull(when = When.MAYBE) public open fun foo(/*0*/ @javax.annotation.Nonnull(when = When.ALWAYS) x: kotlin.String, /*1*/ @javax.annotation.Nonnull(when = When.NEVER) y: kotlin.CharSequence?): kotlin.String? public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java index d746497c794..0a45f16e696 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java @@ -66,6 +66,12 @@ public class ForeignAnnotationsNoAnnotationInClasspathTestGenerated extends Abst doTest(fileName); } + @TestMetadata("jsr305NonNullNever.kt") + public void testJsr305NonNullNever() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt"); + doTest(fileName); + } + @TestMetadata("jsr305NullabilityNicknames.kt") public void testJsr305NullabilityNicknames() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityNicknames.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java index 56776cfb8f1..a90e14cec0b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java @@ -66,6 +66,12 @@ public class ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGe doTest(fileName); } + @TestMetadata("jsr305NonNullNever.kt") + public void testJsr305NonNullNever() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt"); + doTest(fileName); + } + @TestMetadata("jsr305NullabilityNicknames.kt") public void testJsr305NullabilityNicknames() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityNicknames.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java index d49b548359c..a2f1d3aebc2 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java @@ -66,6 +66,12 @@ public class ForeignAnnotationsTestGenerated extends AbstractForeignAnnotationsT doTest(fileName); } + @TestMetadata("jsr305NonNullNever.kt") + public void testJsr305NonNullNever() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt"); + doTest(fileName); + } + @TestMetadata("jsr305NullabilityNicknames.kt") public void testJsr305NullabilityNicknames() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityNicknames.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java index 07e739c1e56..9d0dce4a19f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java @@ -66,6 +66,12 @@ public class JavacForeignAnnotationsTestGenerated extends AbstractJavacForeignAn doTest(fileName); } + @TestMetadata("jsr305NonNullNever.kt") + public void testJsr305NonNullNever() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NonNullNever.kt"); + doTest(fileName); + } + @TestMetadata("jsr305NullabilityNicknames.kt") public void testJsr305NullabilityNicknames() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305NullabilityNicknames.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt index 4a56af91530..0775ba5e1b0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt @@ -62,7 +62,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati return when (enumEntryDescriptor.name.asString()) { "ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) - "MAYBE" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE) + "MAYBE", "NEVER" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE) else -> null } }