Fix enhancement when mixing TYPE_USE and non-TYPE_USE annotations

This commit is contained in:
Denis.Zharkov
2021-09-28 11:31:33 +03:00
committed by teamcityserver
parent a5435c0efc
commit 9ac29e0714
13 changed files with 343 additions and 3 deletions
@@ -0,0 +1,89 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
// FILE: spr/Nullable.java
package spr;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierNickname;
import javax.annotation.meta.When;
@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull(when = When.MAYBE)
@TypeQualifierNickname
public @interface Nullable {
}
// FILE: spr/NotNull.java
package spr;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierNickname;
import javax.annotation.meta.When;
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull
@TypeQualifierNickname
public @interface NotNull {
}
// FILE: J1.java
import spr.*;
public interface J1<T> {
@Nullable
T getFoo();
}
// FILE: J2.java
import spr.*;
public class J2 implements J1<String> {
@NotNull
public String getFoo() { return ""; }
}
// FILE: Nonnull.kt
package spr
import javax.annotation.meta.TypeQualifierNickname
import javax.annotation.Nonnull;
// This is a crucial part: NotNull defined in Java has no TYPE_USE target, so it has been applied only to the method
// While on use-site (main.kt) spr.NotNull shall be resolved to Kotlin version with TYPE among target
// So, even while our annotation is type use, we still should consider situation when it's applied to the method/parameter, but not to type
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.TYPE,
)
@Retention(AnnotationRetention.RUNTIME)
@Nonnull
@TypeQualifierNickname
annotation class NotNull
// FILE: main.kt
fun bar(j2: J2) {
j2.foo.length // `j2.foo` is not nullable
}
@@ -0,0 +1,42 @@
package
public fun bar(/*0*/ j2: J2): kotlin.Unit
public interface J1</*0*/ T : kotlin.Any!> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@spr.Nullable public abstract fun getFoo(): @spr.Nullable T?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class J2 : J1<kotlin.String!> {
public constructor J2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@spr.NotNull public open override /*1*/ fun getFoo(): @spr.NotNull kotlin.String
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package spr {
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierNickname public final annotation class NotNull : kotlin.Annotation {
public constructor NotNull()
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.Target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.VALUE_PARAMETER}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierNickname public final annotation class NotNull : kotlin.Annotation {
public constructor NotNull()
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.Target(allowedTargets = {AnnotationTarget.TYPE}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.Nonnull(when = When.MAYBE) @javax.annotation.meta.TypeQualifierNickname public final annotation class Nullable : kotlin.Annotation {
public constructor Nullable()
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
}
}
@@ -0,0 +1,89 @@
// FIR_IDENTICAL
// SOURCE_RETENTION_ANNOTATIONS
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// JSR305_GLOBAL_REPORT: strict
// FILE: spr/Nullable.java
package spr;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierNickname;
import javax.annotation.meta.When;
@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull(when = When.MAYBE)
@TypeQualifierNickname
public @interface Nullable {
}
// FILE: spr/NotNull.java
package spr;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierNickname;
import javax.annotation.meta.When;
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull
@TypeQualifierNickname
public @interface NotNull {
}
// FILE: J1.java
import spr.*;
public interface J1<T> {
T @Nullable [] getFoo();
}
// FILE: J2.java
import spr.*;
public class J2 implements J1<String> {
@NotNull
public String[] getFoo() { return null; }
}
// FILE: Nonnull.kt
package spr
import javax.annotation.meta.TypeQualifierNickname
import javax.annotation.Nonnull;
// This is a crucial part: NotNull defined in Java has no TYPE_USE target, so it has been applied only to the method
// While on use-site (main.kt) spr.NotNull shall be resolved to Kotlin version with TYPE among target
// So, even while our annotation is type use, we still should consider situation when it's applied to the method/parameter, but not to type
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.TYPE,
)
@Retention(AnnotationRetention.RUNTIME)
@Nonnull
@TypeQualifierNickname
annotation class NotNull
// FILE: main.kt
fun bar(j2: J2) {
j2.foo<!UNSAFE_CALL!>.<!>get(0).length // `j2.foo` is not nullable
}
@@ -0,0 +1,42 @@
package
public fun bar(/*0*/ j2: J2): kotlin.Unit
public interface J1</*0*/ T : kotlin.Any!> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun getFoo(): (@spr.Nullable kotlin.Array<T!>?..@spr.Nullable kotlin.Array<out T!>?)
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class J2 : J1<kotlin.String!> {
public constructor J2()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@spr.NotNull public open override /*1*/ fun getFoo(): kotlin.Array<(out) @spr.NotNull kotlin.String>?
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package spr {
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierNickname public final annotation class NotNull : kotlin.Annotation {
public constructor NotNull()
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.Target(allowedTargets = {AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.VALUE_PARAMETER}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierNickname public final annotation class NotNull : kotlin.Annotation {
public constructor NotNull()
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.Target(allowedTargets = {AnnotationTarget.TYPE}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.Nonnull(when = When.MAYBE) @javax.annotation.meta.TypeQualifierNickname public final annotation class Nullable : kotlin.Annotation {
public constructor Nullable()
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
}
}