Fix loading JSR-305 nicknames for @CheckForNull annotation
For sake of working without jsr305.jar in the classpath `resolveTypeQualifierAnnotation` may return javax.annotation.CheckForNull (although the latter is nickname itself) #KT-19985 Fixed
This commit is contained in:
@@ -16,6 +16,23 @@ public @interface MyNullable {
|
||||
|
||||
}
|
||||
|
||||
// FILE: MyCheckForNull.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
|
||||
@CheckForNull
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MyCheckForNull {
|
||||
|
||||
}
|
||||
|
||||
// FILE: MyNonnull.java
|
||||
import javax.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -50,6 +67,10 @@ public class A {
|
||||
return "";
|
||||
}
|
||||
|
||||
@MyCheckForNull
|
||||
public String baz(@MyNonnull String x, @MyCheckForNull CharSequence y) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
@@ -59,6 +80,10 @@ fun main(a: A) {
|
||||
a.foo("", null)<!UNSAFE_CALL!>.<!>length
|
||||
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "")<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.baz("", null)?.length
|
||||
a.baz("", null)<!UNSAFE_CALL!>.<!>length
|
||||
a.baz(<!NULL_FOR_NONNULL_TYPE!>null<!>, "")<!UNSAFE_CALL!>.<!>length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
|
||||
@@ -6,12 +6,20 @@ public open class A {
|
||||
public constructor A()
|
||||
@MyNullable public final var field: kotlin.String?
|
||||
@MyNonnull public open fun bar(): kotlin.String
|
||||
@MyCheckForNull public open fun baz(/*0*/ @MyNonnull x: kotlin.String, /*1*/ @MyCheckForNull y: kotlin.CharSequence?): kotlin.String?
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@MyNullable public open fun foo(/*0*/ @MyNonnull 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.CheckForNull @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyCheckForNull : kotlin.Annotation {
|
||||
public constructor MyCheckForNull()
|
||||
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
|
||||
}
|
||||
|
||||
@kotlin.annotation.MustBeDocumented @javax.annotation.meta.TypeQualifierNickname @javax.annotation.Nonnull(when = When.ALWAYS) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyNonnull : kotlin.Annotation {
|
||||
public constructor MyNonnull()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
|
||||
Vendored
+24
@@ -18,6 +18,23 @@ public @interface MyNullable {
|
||||
|
||||
}
|
||||
|
||||
// FILE: MyCheckForNull.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
|
||||
@CheckForNull
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MyCheckForNull {
|
||||
|
||||
}
|
||||
|
||||
// FILE: MyNonnull.java
|
||||
import javax.annotation.*;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -52,6 +69,10 @@ public class A {
|
||||
return "";
|
||||
}
|
||||
|
||||
@MyCheckForNull
|
||||
public String baz(@MyNonnull String x, @MyCheckForNull CharSequence y) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
@@ -61,6 +82,9 @@ fun main(a: A) {
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo("", null)<!>.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, "")<!>.length
|
||||
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.baz("", null)<!>.length
|
||||
<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>a.baz(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, "")<!>.length
|
||||
|
||||
a.bar().length
|
||||
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||
|
||||
|
||||
Vendored
+8
@@ -6,12 +6,20 @@ public open class A {
|
||||
public constructor A()
|
||||
@MyNullable public final var field: kotlin.String!
|
||||
@MyNonnull public open fun bar(): kotlin.String!
|
||||
@MyCheckForNull public open fun baz(/*0*/ @MyNonnull x: kotlin.String!, /*1*/ @MyCheckForNull y: kotlin.CharSequence!): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@MyNullable public open fun foo(/*0*/ @MyNonnull 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.CheckForNull @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyCheckForNull : kotlin.Annotation {
|
||||
public constructor MyCheckForNull()
|
||||
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
|
||||
}
|
||||
|
||||
@kotlin.annotation.MustBeDocumented @javax.annotation.meta.TypeQualifierNickname @javax.annotation.Nonnull(when = When.ALWAYS) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) public final annotation class MyNonnull : kotlin.Annotation {
|
||||
public constructor MyNonnull()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
|
||||
+9
-6
@@ -36,11 +36,12 @@ import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgumentValue
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.asFlexibleType
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.isFlexible
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlin.types.unwrapEnhancement
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import java.util.*
|
||||
@@ -76,11 +77,13 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
||||
else -> {
|
||||
val forWarning = annotationTypeQualifierResolver.jsr305State.isWarning()
|
||||
|
||||
annotationTypeQualifierResolver
|
||||
.resolveTypeQualifierAnnotation(annotationDescriptor)
|
||||
?.takeIf { it.fqName == JAVAX_NONNULL_ANNOTATION }
|
||||
?.extractNullabilityTypeFromArgument()
|
||||
?.copy(isForWarningOnly = forWarning)
|
||||
val typeQualifierAnnotation =
|
||||
annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor)
|
||||
?: return null
|
||||
|
||||
// resolveTypeQualifierAnnotation guarantees that `typeQualifierAnnotation` is javax.annotation.NonNull with argument
|
||||
// or javax.annotation.CheckForNull without arguments
|
||||
extractNullability(typeQualifierAnnotation)?.copy(isForWarningOnly = forWarning)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user