From 4d951de616b20feca92f3e9cc9679b2de9e65195 Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Thu, 25 Jan 2018 14:18:39 +0300 Subject: [PATCH] Propagate nullability changes to enhancement for JSR-305 types Fix TypeUtils.makeNullableAsSpecified for SimpleTypeWithEnhancement and FlexibleTypeWithEnhancement: change nullability of enhancement too. This fixes several false-positive warnings, like in KT-20855 and KT-20466. Note that it removes warning in some cases (see testdata change for uselessElvisRightIsNull.kt). However, this removes warning about *unnecessary* elvis, i.e. this fixed introduces weak false-negatives, which is acceptable for the moment. #KT-20855 Fixed Target versions 1.2.30 #KT-20466 Fixed Target versions 1.2.30 #KT-21238 Fixed Target versions 1.2.30 --- .../tests/jsr305/nullabilityWarnings/elvis.kt | 85 ++++++++++++++++ .../jsr305/nullabilityWarnings/elvis.txt | 51 ++++++++++ .../uselessElvisRightIsNull.kt | 2 +- .../nullabilityWarnings/localInference.kt | 96 +++++++++++++++++++ .../nullabilityWarnings/localInference.txt | 50 ++++++++++ .../jsr305/nullabilityWarnings/safeCalls.kt | 72 ++++++++++++++ .../jsr305/nullabilityWarnings/safeCalls.txt | 43 +++++++++ ...sNoAnnotationInClasspathTestGenerated.java | 18 ++++ ...pathWithFastClassReadingTestGenerated.java | 18 ++++ .../ForeignAnnotationsTestGenerated.java | 18 ++++ .../JavacForeignAnnotationsTestGenerated.java | 18 ++++ .../kotlin/types/TypeWithEnhancement.kt | 4 +- 12 files changed, 472 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.txt create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.txt create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.kt create mode 100644 compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.txt diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt new file mode 100644 index 00000000000..577e1f7f007 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt @@ -0,0 +1,85 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// JSR305_GLOBAL_REPORT warn + +// FILE: MyNotNull.java +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierNickname; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.PARAMETER}) +@Nonnull +@TypeQualifierNickname +@Retention(RetentionPolicy.RUNTIME) +public @interface MyNotNull {} + + +// FILE: AnnotatedWithJsr.java +public class AnnotatedWithJsr { + @MyNotNull + public String getString() { + return null; + } + + public void consumeString(@MyNotNull String s) { } +} + + + +// FILE: AnnotatedWithJB.java +import org.jetbrains.annotations.NotNull; + +public class AnnotatedWithJB { + public @NotNull String getString() { + return "hello"; + } + + public void consumeString(@NotNull String s) { } +} + + +// FILE: PlainJava.java +public class PlainJava { + public String getString() { + return null; + } + + public void consumeString(String s) { } +} + + +// FILE: main.kt +val jsr: AnnotatedWithJsr = AnnotatedWithJsr() +val jsrNullable: AnnotatedWithJsr? = null + +val jb: AnnotatedWithJB = AnnotatedWithJB() +val jbNullable: AnnotatedWithJB? = null + +val platform: PlainJava = PlainJava() +val platformNullable: PlainJava? = null + +object Elvis { + fun fromJava() { + val a = jsr.string ?: "" + val b = jsrNullable?.string ?: "" + + val c = jb.string ?: "" + val d = jbNullable?.string ?: "" + + val e = platform.string ?: "" + val f = platformNullable?.string ?: "" + } + + fun toJava(nullableString: String?) { + val b = jsr.consumeString(nullableString ?: "") + val d = jsrNullable?.consumeString(nullableString ?: "") + + val f = jb.consumeString(nullableString ?: "") + val h = jbNullable?.consumeString(nullableString ?: "") + + val j = platform.consumeString(nullableString ?: "") + val l = platformNullable?.consumeString(nullableString ?: "") + } +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.txt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.txt new file mode 100644 index 00000000000..1b14a9740c4 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.txt @@ -0,0 +1,51 @@ +package + +public val jb: AnnotatedWithJB +public val jbNullable: AnnotatedWithJB? = null +public val jsr: AnnotatedWithJsr +public val jsrNullable: AnnotatedWithJsr? = null +public val platform: PlainJava +public val platformNullable: PlainJava? = null + +public open class AnnotatedWithJB { + public constructor AnnotatedWithJB() + public open fun consumeString(/*0*/ @org.jetbrains.annotations.NotNull s: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open fun getString(): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class AnnotatedWithJsr { + public constructor AnnotatedWithJsr() + public open fun consumeString(/*0*/ @MyNotNull s: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyNotNull public open fun getString(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object Elvis { + private constructor Elvis() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun fromJava(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun toJava(/*0*/ nullableString: kotlin.String?): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.VALUE_PARAMETER}) @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierNickname @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyNotNull : kotlin.Annotation { + public constructor MyNotNull() + 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 +} + +public open class PlainJava { + public constructor PlainJava() + public open fun consumeString(/*0*/ s: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun getString(): 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/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt index 6f14996b996..a45fb76b54d 100644 --- a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/fromPlatformTypes/uselessElvisRightIsNull.kt @@ -28,7 +28,7 @@ fun test() { foo(a) val b = JJ.staticNN ?: null foo(b) - val c = JJJ.staticNNN ?: null + val c = JJJ.staticNNN ?: null foo(c) } diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt new file mode 100644 index 00000000000..91a649fc727 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt @@ -0,0 +1,96 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_EXPRESSION +// JSR305_GLOBAL_REPORT warn + +// FILE: MyNotNull.java +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierNickname; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.PARAMETER}) +@Nonnull +@TypeQualifierNickname +@Retention(RetentionPolicy.RUNTIME) +public @interface MyNotNull {} + + +// FILE: AnnotatedWithJsr.java +public class AnnotatedWithJsr { + @MyNotNull + public String getString() { + return null; + } + + public void consumeString(@MyNotNull String s) { } +} + + + +// FILE: AnnotatedWithJB.java +import org.jetbrains.annotations.NotNull; + +public class AnnotatedWithJB { + public @NotNull String getString() { + return "hello"; + } + + public void consumeString(@NotNull String s) { } +} + + +// FILE: PlainJava.java +public class PlainJava { + public String getString() { + return null; + } + + public void consumeString(String s) { } +} + + +// FILE: main.kt +val jsr: AnnotatedWithJsr = AnnotatedWithJsr() +val jsrNullable: AnnotatedWithJsr? = null + +val jb: AnnotatedWithJB = AnnotatedWithJB() +val jbNullable: AnnotatedWithJB? = null + +val platform: PlainJava = PlainJava() +val platformNullable: PlainJava? = null + +val a = jsr.string +val b = jsrNullable?.string +val c = jb.string +val d = jbNullable?.string +val e = platform.string +val f = platformNullable?.string + +fun evlis() { + // JSR + val r1 = a ?: "" + val r2 = b ?: "" + + // JB + val r3 = c ?: "" + val r4 = d ?: "" + + // Platform + val r5 = e ?: "" + val r6 = f ?: "" +} + +fun ifChecksAndSmartCasts() { + // JSR + val r1 = if (a == null) 42 else a.length + val r2 = if (b == null) 42 else b.length + + // JB + val r3 = if (c == null) 42 else c.length + val r4 = if (d == null) 42 else d.length + + // Platform + val r5 = if (e == null) 42 else e.length + val r6 = if (f == null) 42 else f.length +} \ No newline at end of file diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.txt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.txt new file mode 100644 index 00000000000..db00c64c2d7 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.txt @@ -0,0 +1,50 @@ +package + +public val a: kotlin.String! +public val b: kotlin.String? +public val c: kotlin.String +public val d: kotlin.String? +public val e: kotlin.String! +public val f: kotlin.String? +public val jb: AnnotatedWithJB +public val jbNullable: AnnotatedWithJB? = null +public val jsr: AnnotatedWithJsr +public val jsrNullable: AnnotatedWithJsr? = null +public val platform: PlainJava +public val platformNullable: PlainJava? = null +public fun evlis(): kotlin.Unit +public fun ifChecksAndSmartCasts(): kotlin.Unit + +public open class AnnotatedWithJB { + public constructor AnnotatedWithJB() + public open fun consumeString(/*0*/ @org.jetbrains.annotations.NotNull s: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open fun getString(): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class AnnotatedWithJsr { + public constructor AnnotatedWithJsr() + public open fun consumeString(/*0*/ @MyNotNull s: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyNotNull public open fun getString(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.VALUE_PARAMETER}) @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierNickname @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyNotNull : kotlin.Annotation { + public constructor MyNotNull() + 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 +} + +public open class PlainJava { + public constructor PlainJava() + public open fun consumeString(/*0*/ s: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun getString(): 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/jsr305/nullabilityWarnings/safeCalls.kt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.kt new file mode 100644 index 00000000000..401bd236b74 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.kt @@ -0,0 +1,72 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// JSR305_GLOBAL_REPORT warn + +// FILE: MyNotNull.java +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierNickname; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.PARAMETER}) +@Nonnull +@TypeQualifierNickname +@Retention(RetentionPolicy.RUNTIME) +public @interface MyNotNull {} + + +// FILE: AnnotatedWithJsr.java +public class AnnotatedWithJsr { + @MyNotNull + public String getString() { + return null; + } + + public void consumeString(@MyNotNull String s) { } +} + + + +// FILE: AnnotatedWithJB.java +import org.jetbrains.annotations.NotNull; + +public class AnnotatedWithJB { + public @NotNull String getString() { + return "hello"; + } + + public void consumeString(@NotNull String s) { } +} + + +// FILE: PlainJava.java +public class PlainJava { + public String getString() { + return null; + } + + public void consumeString(String s) { } +} + + +// FILE: main.kt +val jsr: AnnotatedWithJsr = AnnotatedWithJsr() +val jsrNullable: AnnotatedWithJsr? = null + +val jb: AnnotatedWithJB = AnnotatedWithJB() +val jbNullable: AnnotatedWithJB? = null + +val platform: PlainJava = PlainJava() +val platformNullable: PlainJava? = null + +fun safeCalls() { + val a = jsr.string?.length + val b = jsrNullable?.string?.length + + val c = jb.string?.length + val d = jbNullable?.string?.length + + val e = platform.string?.length + val f = platformNullable?.string?.length +} diff --git a/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.txt b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.txt new file mode 100644 index 00000000000..debefc5db28 --- /dev/null +++ b/compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.txt @@ -0,0 +1,43 @@ +package + +public val jb: AnnotatedWithJB +public val jbNullable: AnnotatedWithJB? = null +public val jsr: AnnotatedWithJsr +public val jsrNullable: AnnotatedWithJsr? = null +public val platform: PlainJava +public val platformNullable: PlainJava? = null +public fun safeCalls(): kotlin.Unit + +public open class AnnotatedWithJB { + public constructor AnnotatedWithJB() + public open fun consumeString(/*0*/ @org.jetbrains.annotations.NotNull s: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull public open fun getString(): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class AnnotatedWithJsr { + public constructor AnnotatedWithJsr() + public open fun consumeString(/*0*/ @MyNotNull s: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @MyNotNull public open fun getString(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.VALUE_PARAMETER}) @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierNickname @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyNotNull : kotlin.Annotation { + public constructor MyNotNull() + 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 +} + +public open class PlainJava { + public constructor PlainJava() + public open fun consumeString(/*0*/ s: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun getString(): 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 a67f6d7c064..f0ecc8b6c41 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathTestGenerated.java @@ -128,6 +128,18 @@ public class ForeignAnnotationsNoAnnotationInClasspathTestGenerated extends Abst KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("elvis.kt") + public void testElvis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt"); + doTest(fileName); + } + + @TestMetadata("localInference.kt") + public void testLocalInference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt"); + doTest(fileName); + } + @TestMetadata("nullabilityGenerics.kt") public void testNullabilityGenerics() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt"); @@ -140,6 +152,12 @@ public class ForeignAnnotationsNoAnnotationInClasspathTestGenerated extends Abst doTest(fileName); } + @TestMetadata("safeCalls.kt") + public void testSafeCalls() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java index 76ab343dfce..4075003e611 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGenerated.java @@ -128,6 +128,18 @@ public class ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGe KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("elvis.kt") + public void testElvis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt"); + doTest(fileName); + } + + @TestMetadata("localInference.kt") + public void testLocalInference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt"); + doTest(fileName); + } + @TestMetadata("nullabilityGenerics.kt") public void testNullabilityGenerics() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt"); @@ -140,6 +152,12 @@ public class ForeignAnnotationsNoAnnotationInClasspathWithFastClassReadingTestGe doTest(fileName); } + @TestMetadata("safeCalls.kt") + public void testSafeCalls() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java index 87a1dca01f3..4b3a1428e82 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/ForeignAnnotationsTestGenerated.java @@ -128,6 +128,18 @@ public class ForeignAnnotationsTestGenerated extends AbstractForeignAnnotationsT KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("elvis.kt") + public void testElvis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt"); + doTest(fileName); + } + + @TestMetadata("localInference.kt") + public void testLocalInference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt"); + doTest(fileName); + } + @TestMetadata("nullabilityGenerics.kt") public void testNullabilityGenerics() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt"); @@ -140,6 +152,12 @@ public class ForeignAnnotationsTestGenerated extends AbstractForeignAnnotationsT doTest(fileName); } + @TestMetadata("safeCalls.kt") + public void testSafeCalls() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java index 50705420a89..32435a09f8d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/JavacForeignAnnotationsTestGenerated.java @@ -128,6 +128,18 @@ public class JavacForeignAnnotationsTestGenerated extends AbstractJavacForeignAn KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("elvis.kt") + public void testElvis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/elvis.kt"); + doTest(fileName); + } + + @TestMetadata("localInference.kt") + public void testLocalInference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/localInference.kt"); + doTest(fileName); + } + @TestMetadata("nullabilityGenerics.kt") public void testNullabilityGenerics() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/nullabilityGenerics.kt"); @@ -140,6 +152,12 @@ public class JavacForeignAnnotationsTestGenerated extends AbstractJavacForeignAn doTest(fileName); } + @TestMetadata("safeCalls.kt") + public void testSafeCalls() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/safeCalls.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/jsr305/nullabilityWarnings/simple.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt index 83aae9a7713..a589c334369 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeWithEnhancement.kt @@ -38,7 +38,7 @@ class SimpleTypeWithEnhancement( = origin.replaceAnnotations(newAnnotations).wrapEnhancement(enhancement) as SimpleType override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType - = origin.makeNullableAsSpecified(newNullability).wrapEnhancement(enhancement) as SimpleType + = origin.makeNullableAsSpecified(newNullability).wrapEnhancement(enhancement.unwrap().makeNullableAsSpecified(newNullability)) as SimpleType } class FlexibleTypeWithEnhancement( @@ -51,7 +51,7 @@ class FlexibleTypeWithEnhancement( = origin.replaceAnnotations(newAnnotations).wrapEnhancement(enhancement) override fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType - = origin.makeNullableAsSpecified(newNullability).wrapEnhancement(enhancement) + = origin.makeNullableAsSpecified(newNullability).wrapEnhancement(enhancement.unwrap().makeNullableAsSpecified(newNullability)) override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String = origin.render(renderer, options)