Support TypeQualifierDefault from JSR 305 for nullability qualifiers
#KT-10942 Fixed
This commit is contained in:
compiler/testData/foreignAnnotations/annotations/javax/annotation/ParametersAreNonnullByDefault.java
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package javax.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
import javax.annotation.meta.TypeQualifierDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation can be applied to a package, class or method to indicate that
|
||||||
|
* the method parameters in that element are nonnull by default unless there is:
|
||||||
|
* <ul>
|
||||||
|
* <li>An explicit nullness annotation
|
||||||
|
* <li>The method overrides a method in a superclass (in which case the
|
||||||
|
* annotation of the corresponding parameter in the superclass applies)
|
||||||
|
* <li>There is a default parameter annotation (like {@link ParametersAreNullableByDefault})
|
||||||
|
* applied to a more tightly nested element.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see Nonnull
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Nonnull
|
||||||
|
@TypeQualifierDefault(ElementType.PARAMETER)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ParametersAreNonnullByDefault {
|
||||||
|
}
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: FieldsAreNullable.java
|
||||||
|
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.CheckForNull;
|
||||||
|
import javax.annotation.meta.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@CheckForNull
|
||||||
|
@TypeQualifierDefault({ElementType.FIELD})
|
||||||
|
public @interface FieldsAreNullable {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import javax.annotation.*;
|
||||||
|
|
||||||
|
@FieldsAreNullable
|
||||||
|
public class A {
|
||||||
|
public String field = null;
|
||||||
|
@Nonnull
|
||||||
|
public String nonNullField = "";
|
||||||
|
|
||||||
|
public String foo(String q, @Nonnull String x, @CheckForNull CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(a: A) {
|
||||||
|
// foo is platform
|
||||||
|
a.foo("", "", null)?.length
|
||||||
|
a.foo("", "", null).length
|
||||||
|
a.foo(null, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a.bar().length
|
||||||
|
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a.field?.length
|
||||||
|
a.field<!UNSAFE_CALL!>.<!>length
|
||||||
|
a.field = null
|
||||||
|
|
||||||
|
a.nonNullField<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
a.nonNullField.length
|
||||||
|
a.nonNullField = <!NULL_FOR_NONNULL_TYPE!>null<!>
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: A): kotlin.Unit
|
||||||
|
|
||||||
|
@FieldsAreNullable public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public final var field: kotlin.String?
|
||||||
|
@javax.annotation.Nonnull public final var nonNullField: 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
|
||||||
|
public open fun foo(/*0*/ q: kotlin.String!, /*1*/ @javax.annotation.Nonnull x: kotlin.String, /*2*/ @javax.annotation.CheckForNull 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.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.CheckForNull @javax.annotation.meta.TypeQualifierDefault(value = {ElementType.FIELD}) public final annotation class FieldsAreNullable : kotlin.Annotation {
|
||||||
|
public constructor FieldsAreNullable()
|
||||||
|
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
|
||||||
|
}
|
||||||
Vendored
+158
@@ -0,0 +1,158 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: NonNullApi.java
|
||||||
|
|
||||||
|
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.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Target(ElementType.CLASS)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull
|
||||||
|
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
|
||||||
|
public @interface NonNullApi {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: NullableApi.java
|
||||||
|
|
||||||
|
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.CheckForNull;
|
||||||
|
import javax.annotation.meta.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Target(ElementType.CLASS)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@CheckForNull
|
||||||
|
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
|
||||||
|
public @interface NullableApi {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public class A {
|
||||||
|
public String foo1(String x) { return ""; }
|
||||||
|
public String foo2(String x) { return ""; }
|
||||||
|
public String foo3(String x) { return ""; }
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String bar1(@Nullable String x) { return ""; }
|
||||||
|
@Nullable
|
||||||
|
public String bar2(@Nullable String x) { return ""; }
|
||||||
|
|
||||||
|
public String baz(@Nonnull String x) { return ""; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: AInt.java
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public interface AInt {
|
||||||
|
public CharSequence foo1(String x);
|
||||||
|
public CharSequence foo2(String x);
|
||||||
|
public CharSequence foo3(String x);
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public CharSequence bar1(@Nullable String x);
|
||||||
|
@Nullable
|
||||||
|
public CharSequence bar2(@Nullable String x);
|
||||||
|
|
||||||
|
public CharSequence baz(@Nonnull String x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: B.java
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
@NullableApi
|
||||||
|
public class B extends A implements AInt {
|
||||||
|
// conflicts
|
||||||
|
public String foo1(String x) { return ""; }
|
||||||
|
|
||||||
|
// no conflicts
|
||||||
|
@Nonnull
|
||||||
|
public String foo2(@Nonnull String x) { return ""; }
|
||||||
|
|
||||||
|
// fake override for foo3 shouldn't have any conflicts
|
||||||
|
|
||||||
|
// no conflicts
|
||||||
|
public String bar1(String x) { return ""; }
|
||||||
|
|
||||||
|
// conflicts
|
||||||
|
public String baz(String x) { return ""; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: C.java
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public class C extends A implements AInt {
|
||||||
|
// no conflicts
|
||||||
|
public String foo1(String x) { return ""; }
|
||||||
|
|
||||||
|
// no conflicts
|
||||||
|
public String foo2(@Nonnull String x) { return ""; }
|
||||||
|
|
||||||
|
// fake override for foo3 shouldn't have any conflicts
|
||||||
|
|
||||||
|
// no conflicts, covariant override
|
||||||
|
public String bar1(String x) { return ""; }
|
||||||
|
// no conflicts
|
||||||
|
@Nullable
|
||||||
|
public String bar2(@Nullable String x) { return ""; }
|
||||||
|
|
||||||
|
// no conflicts
|
||||||
|
public String baz(String x) { return ""; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(a: A, b: B, c: C) {
|
||||||
|
a.foo1(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
a.foo2(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
a.foo3(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
a.bar1(null)<!UNSAFE_CALL!>.<!>length
|
||||||
|
a.bar2(null)<!UNSAFE_CALL!>.<!>length
|
||||||
|
a.baz(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
|
||||||
|
b.foo1(null).length
|
||||||
|
b.foo1(null)?.length
|
||||||
|
b.foo2(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
b.foo3(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
b.bar1(null)<!UNSAFE_CALL!>.<!>length
|
||||||
|
b.bar2(null)<!UNSAFE_CALL!>.<!>length
|
||||||
|
b.baz(null).length
|
||||||
|
b.baz(null)?.length
|
||||||
|
|
||||||
|
c.foo1(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
c.foo2(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
c.foo3(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
c.bar1(null).length
|
||||||
|
c.bar1(null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
c.bar2(null)<!UNSAFE_CALL!>.<!>length
|
||||||
|
c.baz(<!NULL_FOR_NONNULL_TYPE!>null<!>).length
|
||||||
|
}
|
||||||
Vendored
+68
@@ -0,0 +1,68 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: A, /*1*/ b: B, /*2*/ c: C): kotlin.Unit
|
||||||
|
|
||||||
|
@NonNullApi public open class A {
|
||||||
|
public constructor A()
|
||||||
|
@javax.annotation.Nullable public open fun bar1(/*0*/ @javax.annotation.Nullable x: kotlin.String?): kotlin.String?
|
||||||
|
@javax.annotation.Nullable public open fun bar2(/*0*/ @javax.annotation.Nullable x: kotlin.String?): kotlin.String?
|
||||||
|
public open fun baz(/*0*/ @javax.annotation.Nonnull x: kotlin.String): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo1(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open fun foo2(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open fun foo3(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNullApi public interface AInt {
|
||||||
|
@javax.annotation.Nullable public abstract fun bar1(/*0*/ @javax.annotation.Nullable x: kotlin.String?): kotlin.CharSequence?
|
||||||
|
@javax.annotation.Nullable public abstract fun bar2(/*0*/ @javax.annotation.Nullable x: kotlin.String?): kotlin.CharSequence?
|
||||||
|
public abstract fun baz(/*0*/ @javax.annotation.Nonnull x: kotlin.String): kotlin.CharSequence
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun foo1(/*0*/ x: kotlin.String): kotlin.CharSequence
|
||||||
|
public abstract fun foo2(/*0*/ x: kotlin.String): kotlin.CharSequence
|
||||||
|
public abstract fun foo3(/*0*/ x: kotlin.String): kotlin.CharSequence
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
@NullableApi public open class B : A, AInt {
|
||||||
|
public constructor B()
|
||||||
|
public open override /*2*/ fun bar1(/*0*/ x: kotlin.String?): kotlin.String?
|
||||||
|
@javax.annotation.Nullable public open override /*2*/ /*fake_override*/ fun bar2(/*0*/ @javax.annotation.Nullable x: kotlin.String?): kotlin.String?
|
||||||
|
public open override /*2*/ fun baz(/*0*/ x: kotlin.String!): kotlin.String!
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ fun foo1(/*0*/ x: kotlin.String!): kotlin.String!
|
||||||
|
@javax.annotation.Nonnull public open override /*2*/ fun foo2(/*0*/ @javax.annotation.Nonnull x: kotlin.String): kotlin.String
|
||||||
|
public open override /*2*/ /*fake_override*/ fun foo3(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNullApi public open class C : A, AInt {
|
||||||
|
public constructor C()
|
||||||
|
public open override /*2*/ fun bar1(/*0*/ x: kotlin.String!): kotlin.String
|
||||||
|
@javax.annotation.Nullable public open override /*2*/ fun bar2(/*0*/ @javax.annotation.Nullable x: kotlin.String?): kotlin.String?
|
||||||
|
public open override /*2*/ fun baz(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ fun foo1(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open override /*2*/ fun foo2(/*0*/ @javax.annotation.Nonnull x: kotlin.String): kotlin.String
|
||||||
|
public open override /*2*/ /*fake_override*/ fun foo3(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierDefault(value = {ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) public final annotation class NonNullApi : kotlin.Annotation {
|
||||||
|
public constructor NonNullApi()
|
||||||
|
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 = {}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.CheckForNull @javax.annotation.meta.TypeQualifierDefault(value = {ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) public final annotation class NullableApi : kotlin.Annotation {
|
||||||
|
public constructor NullableApi()
|
||||||
|
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
|
||||||
|
}
|
||||||
Vendored
+186
@@ -0,0 +1,186 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// FILE: NonNullApi.java
|
||||||
|
|
||||||
|
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.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Target(ElementType.PACKAGE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull
|
||||||
|
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
|
||||||
|
public @interface NonNullApi {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: NullableApi.java
|
||||||
|
|
||||||
|
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.CheckForNull;
|
||||||
|
import javax.annotation.meta.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Target(ElementType.PACKAGE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@CheckForNull
|
||||||
|
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
|
||||||
|
public @interface NullableApi {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: FieldsAreNullable.java
|
||||||
|
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.CheckForNull;
|
||||||
|
import javax.annotation.meta.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@CheckForNull
|
||||||
|
@TypeQualifierDefault({ElementType.FIELD})
|
||||||
|
public @interface FieldsAreNullable {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import javax.annotation.CheckForNull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public class A {
|
||||||
|
public String field = null;
|
||||||
|
|
||||||
|
public String foo(String x, @CheckForNull CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NullableApi
|
||||||
|
public String foobar(String x, @Nonnull CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public java.util.List<String> baz() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NullableApi
|
||||||
|
public class B {
|
||||||
|
public String field = null;
|
||||||
|
|
||||||
|
public String foo(String x, @Nonnull CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public String foobar(String x, @Nullable CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public java.util.List<String> baz() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FieldsAreNullable
|
||||||
|
public class C {
|
||||||
|
public String field = null;
|
||||||
|
|
||||||
|
public String foo(String x, @Nullable CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NullableApi
|
||||||
|
public String foobar(String x, @Nullable CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public java.util.List<String> baz() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(a: A, b: A.B, c: A.C) {
|
||||||
|
a.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
a.foo("", null).length
|
||||||
|
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a.foobar(null, "")<!UNSAFE_CALL!>.<!>length
|
||||||
|
a.foobar("", <!NULL_FOR_NONNULL_TYPE!>null<!>)?.length
|
||||||
|
|
||||||
|
a.bar().length
|
||||||
|
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a.field<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
a.field.length
|
||||||
|
|
||||||
|
a.baz()<!UNSAFE_CALL!>.<!>get(0)
|
||||||
|
a.baz()!!.get(0).get(0)
|
||||||
|
a.baz()!!.get(0)?.get(0)
|
||||||
|
|
||||||
|
// b
|
||||||
|
b.foo("", <!NULL_FOR_NONNULL_TYPE!>null<!>)?.length
|
||||||
|
b.foo("", <!NULL_FOR_NONNULL_TYPE!>null<!>)<!UNSAFE_CALL!>.<!>length
|
||||||
|
b.foo(null, "")<!UNSAFE_CALL!>.<!>length
|
||||||
|
|
||||||
|
b.foobar(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
b.foobar("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
|
||||||
|
b.bar()<!UNSAFE_CALL!>.<!>length
|
||||||
|
b.bar()!!.length
|
||||||
|
|
||||||
|
b.field?.length
|
||||||
|
b.field<!UNSAFE_CALL!>.<!>length
|
||||||
|
|
||||||
|
b.baz()<!UNSAFE_CALL!>.<!>get(0)
|
||||||
|
b.baz()!!.get(0).get(0)
|
||||||
|
b.baz()!!.get(0)?.get(0)
|
||||||
|
|
||||||
|
// c
|
||||||
|
c.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
c.foo("", null).length
|
||||||
|
c.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
c.foobar(null, "")<!UNSAFE_CALL!>.<!>length
|
||||||
|
c.foobar("", null)?.length
|
||||||
|
|
||||||
|
c.bar().length
|
||||||
|
c.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
c.field?.length
|
||||||
|
c.field<!UNSAFE_CALL!>.<!>length
|
||||||
|
|
||||||
|
c.baz()<!UNSAFE_CALL!>.<!>get(0)
|
||||||
|
c.baz()!!.get(0).get(0)
|
||||||
|
c.baz()!!.get(0)?.get(0)
|
||||||
|
}
|
||||||
Vendored
+60
@@ -0,0 +1,60 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: A, /*1*/ b: A.B, /*2*/ c: A.C): kotlin.Unit
|
||||||
|
|
||||||
|
@NonNullApi public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public final var field: kotlin.String
|
||||||
|
public open fun bar(): kotlin.String
|
||||||
|
@javax.annotation.Nullable public open fun baz(): kotlin.collections.(Mutable)List<kotlin.String!>?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(/*0*/ x: kotlin.String, /*1*/ @javax.annotation.CheckForNull y: kotlin.CharSequence?): kotlin.String
|
||||||
|
@NullableApi public open fun foobar(/*0*/ x: kotlin.String?, /*1*/ @javax.annotation.Nonnull 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
|
||||||
|
|
||||||
|
@NullableApi public open inner class B {
|
||||||
|
public constructor B()
|
||||||
|
public final var field: kotlin.String?
|
||||||
|
public open fun bar(): kotlin.String?
|
||||||
|
@javax.annotation.Nullable public open fun baz(): kotlin.collections.(Mutable)List<kotlin.String!>?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(/*0*/ x: kotlin.String?, /*1*/ @javax.annotation.Nonnull y: kotlin.CharSequence): kotlin.String?
|
||||||
|
@NonNullApi public open fun foobar(/*0*/ x: kotlin.String, /*1*/ @javax.annotation.Nullable 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
|
||||||
|
}
|
||||||
|
|
||||||
|
@FieldsAreNullable public open inner class C {
|
||||||
|
public constructor C()
|
||||||
|
public final var field: kotlin.String?
|
||||||
|
public open fun bar(): kotlin.String
|
||||||
|
@javax.annotation.Nullable public open fun baz(): kotlin.collections.(Mutable)List<kotlin.String!>?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(/*0*/ x: kotlin.String, /*1*/ @javax.annotation.Nullable y: kotlin.CharSequence?): kotlin.String
|
||||||
|
@NullableApi public open fun foobar(/*0*/ x: kotlin.String?, /*1*/ @javax.annotation.Nullable 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.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.CheckForNull @javax.annotation.meta.TypeQualifierDefault(value = {ElementType.FIELD}) public final annotation class FieldsAreNullable : kotlin.Annotation {
|
||||||
|
public constructor FieldsAreNullable()
|
||||||
|
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 = {}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.Nonnull @javax.annotation.meta.TypeQualifierDefault(value = {ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) public final annotation class NonNullApi : kotlin.Annotation {
|
||||||
|
public constructor NonNullApi()
|
||||||
|
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 = {}) @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.MustBeDocumented @javax.annotation.CheckForNull @javax.annotation.meta.TypeQualifierDefault(value = {ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) public final annotation class NullableApi : kotlin.Annotation {
|
||||||
|
public constructor NullableApi()
|
||||||
|
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
|
||||||
|
}
|
||||||
Vendored
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import javax.annotation.*;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public class A {
|
||||||
|
@Nullable public String field = null;
|
||||||
|
|
||||||
|
public String foo(String q, @Nonnull String x, @CheckForNull CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(a: A) {
|
||||||
|
// foo is platform
|
||||||
|
a.foo("", "", null)?.length
|
||||||
|
a.foo("", "", null).length
|
||||||
|
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a.bar().length
|
||||||
|
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a.field?.length
|
||||||
|
a.field<!UNSAFE_CALL!>.<!>length
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: A): kotlin.Unit
|
||||||
|
|
||||||
|
@javax.annotation.ParametersAreNonnullByDefault public open class A {
|
||||||
|
public constructor A()
|
||||||
|
@javax.annotation.Nullable 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
|
||||||
|
public open fun foo(/*0*/ q: kotlin.String, /*1*/ @javax.annotation.Nonnull x: kotlin.String, /*2*/ @javax.annotation.CheckForNull 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
|
||||||
|
}
|
||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
// RENDER_PACKAGE: test
|
||||||
|
// RENDER_PACKAGE: test2
|
||||||
|
|
||||||
|
// FILE: test/package-info.java
|
||||||
|
|
||||||
|
@javax.annotation.ParametersAreNonnullByDefault()
|
||||||
|
package test;
|
||||||
|
|
||||||
|
// FILE: test/A.java
|
||||||
|
|
||||||
|
package test;
|
||||||
|
|
||||||
|
import javax.annotation.*;
|
||||||
|
|
||||||
|
public class A {
|
||||||
|
@Nullable public String field = null;
|
||||||
|
|
||||||
|
public String foo(String q, @Nonnull String x, @CheckForNull CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test2/A2.java
|
||||||
|
|
||||||
|
package test2;
|
||||||
|
|
||||||
|
import javax.annotation.*;
|
||||||
|
|
||||||
|
public class A2 {
|
||||||
|
@Nullable public String field = null;
|
||||||
|
|
||||||
|
public String foo(String q, @Nonnull String x, @CheckForNull CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
import test.A
|
||||||
|
import test2.A2
|
||||||
|
|
||||||
|
fun main(a: A, a2: A2) {
|
||||||
|
a.foo("", "", null)?.length
|
||||||
|
a.foo("", "", null).length
|
||||||
|
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a.bar().length
|
||||||
|
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a.field?.length
|
||||||
|
a.field<!UNSAFE_CALL!>.<!>length
|
||||||
|
|
||||||
|
a2.foo("", "", null)?.length
|
||||||
|
a2.foo("", "", null).length
|
||||||
|
a2.foo(null, <!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a2.bar().length
|
||||||
|
a2.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a2.field?.length
|
||||||
|
a2.field<!UNSAFE_CALL!>.<!>length
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public open class A {
|
||||||
|
public constructor A()
|
||||||
|
@javax.annotation.Nullable 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
|
||||||
|
public open fun foo(/*0*/ q: kotlin.String, /*1*/ @javax.annotation.Nonnull x: kotlin.String, /*2*/ @javax.annotation.CheckForNull 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
|
||||||
|
}
|
||||||
|
|
||||||
|
package test2
|
||||||
|
|
||||||
|
public open class A2 {
|
||||||
|
public constructor A2()
|
||||||
|
@javax.annotation.Nullable 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
|
||||||
|
public open fun foo(/*0*/ q: kotlin.String!, /*1*/ @javax.annotation.Nonnull x: kotlin.String, /*2*/ @javax.annotation.CheckForNull 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
|
||||||
|
}
|
||||||
|
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: test.A, /*1*/ a2: test2.A2): kotlin.Unit
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// 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.METHOD, ElementType.PARAMETER})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull(when = When.MAYBE)
|
||||||
|
@TypeQualifierNickname
|
||||||
|
public @interface Nullable {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: spr/NonNullApi.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.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Target(ElementType.CLASS)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull
|
||||||
|
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
|
||||||
|
public @interface NonNullApi {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import spr.*;
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public class A {
|
||||||
|
public String field = null;
|
||||||
|
|
||||||
|
public String foo(String x, @Nullable CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public java.util.List<String> baz() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(a: A) {
|
||||||
|
a.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
a.foo("", null).length
|
||||||
|
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a.bar().length
|
||||||
|
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a.field?.length
|
||||||
|
a.field.length
|
||||||
|
|
||||||
|
a.baz()<!UNSAFE_CALL!>.<!>get(0)
|
||||||
|
a.baz()!!.get(0).get(0)
|
||||||
|
a.baz()!!.get(0)?.get(0)
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: A): kotlin.Unit
|
||||||
|
|
||||||
|
@spr.NonNullApi public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public final var field: kotlin.String!
|
||||||
|
public open fun bar(): kotlin.String
|
||||||
|
@spr.Nullable public open fun baz(): kotlin.collections.(Mutable)List<kotlin.String!>?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(/*0*/ x: kotlin.String, /*1*/ @spr.Nullable 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
|
||||||
|
}
|
||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
// RENDER_PACKAGE: test
|
||||||
|
|
||||||
|
// 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.METHOD, ElementType.PARAMETER})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull(when = When.MAYBE)
|
||||||
|
@TypeQualifierNickname
|
||||||
|
public @interface Nullable {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: spr/NonNullApi.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.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Target(ElementType.PACKAGE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull
|
||||||
|
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
|
||||||
|
public @interface NonNullApi {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test/package-info.java
|
||||||
|
|
||||||
|
@spr.NonNullApi()
|
||||||
|
package test;
|
||||||
|
|
||||||
|
// FILE: test/A.java
|
||||||
|
|
||||||
|
package test;
|
||||||
|
|
||||||
|
import spr.*;
|
||||||
|
|
||||||
|
public class A {
|
||||||
|
public String field = null;
|
||||||
|
|
||||||
|
public String foo(String x, @Nullable CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public java.util.List<String> baz() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(a: test.A) {
|
||||||
|
a.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
a.foo("", null).length
|
||||||
|
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a.bar().length
|
||||||
|
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a.field?.length
|
||||||
|
a.field.length
|
||||||
|
|
||||||
|
a.baz()<!UNSAFE_CALL!>.<!>get(0)
|
||||||
|
a.baz()!!.get(0).get(0)
|
||||||
|
a.baz()!!.get(0)?.get(0)
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public final var field: kotlin.String!
|
||||||
|
public open fun bar(): kotlin.String
|
||||||
|
@spr.Nullable public open fun baz(): kotlin.collections.(Mutable)List<kotlin.String!>?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(/*0*/ x: kotlin.String, /*1*/ @spr.Nullable 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
|
||||||
|
}
|
||||||
|
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: test.A): kotlin.Unit
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package 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.MAYBE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface CheckForNull {
|
||||||
|
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
package javax.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
import javax.annotation.meta.TypeQualifier;
|
||||||
|
import javax.annotation.meta.TypeQualifierValidator;
|
||||||
|
import javax.annotation.meta.When;
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@TypeQualifier
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Nonnull {
|
||||||
|
When when() default When.ALWAYS;
|
||||||
|
|
||||||
|
static class Checker implements TypeQualifierValidator<Nonnull> {
|
||||||
|
|
||||||
|
public When forConstantValue(Nonnull qualifierqualifierArgument,
|
||||||
|
Object value) {
|
||||||
|
if (value == null)
|
||||||
|
return When.NEVER;
|
||||||
|
return When.ALWAYS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package 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.UNKNOWN)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Nullable {
|
||||||
|
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package javax.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
import javax.annotation.meta.TypeQualifierDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation can be applied to a package, class or method to indicate that
|
||||||
|
* the method parameters in that element are nonnull by default unless there is:
|
||||||
|
* <ul>
|
||||||
|
* <li>An explicit nullness annotation
|
||||||
|
* <li>The method overrides a method in a superclass (in which case the
|
||||||
|
* annotation of the corresponding parameter in the superclass applies)
|
||||||
|
* <li>There is a default parameter annotation (like {@link ParametersAreNullableByDefault})
|
||||||
|
* applied to a more tightly nested element.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see Nonnull
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Nonnull
|
||||||
|
@TypeQualifierDefault(ElementType.PARAMETER)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface ParametersAreNonnullByDefault {
|
||||||
|
}
|
||||||
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package javax.annotation.meta;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This qualifier is applied to an annotation to denote that the annotation
|
||||||
|
* should be treated as a type qualifier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Target(ElementType.ANNOTATION_TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface TypeQualifier {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the kinds of values the qualifier can be applied to. If a
|
||||||
|
* numeric class is provided (e.g., Number.class or Integer.class) then the
|
||||||
|
* annotation can also be applied to the corresponding primitive numeric
|
||||||
|
* types.
|
||||||
|
*/
|
||||||
|
Class<?> applicableTo() default Object.class;
|
||||||
|
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package javax.annotation.meta;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This qualifier is applied to an annotation to denote that the annotation
|
||||||
|
* defines a default type qualifier that is visible within the scope of the
|
||||||
|
* element it is applied to.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Target(ElementType.ANNOTATION_TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface TypeQualifierDefault {
|
||||||
|
ElementType[] value() default {};
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package javax.annotation.meta;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This annotation is applied to a annotation, and marks the annotation as being
|
||||||
|
* a qualifier nickname. Applying a nickname annotation X to a element Y should
|
||||||
|
* be interpreted as having the same meaning as applying all of annotations of X
|
||||||
|
* (other than QualifierNickname) to Y.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Thus, you might define a qualifier SocialSecurityNumber as follows:
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
@Documented
|
||||||
|
@TypeQualifierNickname @Pattern("[0-9]{3}-[0-9]{2}-[0-9]{4}")
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface SocialSecurityNumber {
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Target(ElementType.ANNOTATION_TYPE)
|
||||||
|
public @interface TypeQualifierNickname {
|
||||||
|
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package javax.annotation.meta;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public interface TypeQualifierValidator<A extends Annotation> {
|
||||||
|
/**
|
||||||
|
* Given a type qualifier, check to see if a known specific constant value
|
||||||
|
* is an instance of the set of values denoted by the qualifier.
|
||||||
|
*
|
||||||
|
* @param annotation
|
||||||
|
* the type qualifier
|
||||||
|
* @param value
|
||||||
|
* the value to check
|
||||||
|
* @return a value indicating whether or not the value is an member of the
|
||||||
|
* values denoted by the type qualifier
|
||||||
|
*/
|
||||||
|
public @Nonnull
|
||||||
|
When forConstantValue(@Nonnull A annotation, Object value);
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package javax.annotation.meta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to describe the relationship between a qualifier T and the set of values
|
||||||
|
* S possible on an annotated element.
|
||||||
|
*
|
||||||
|
* In particular, an issues should be reported if an ALWAYS or MAYBE value is
|
||||||
|
* used where a NEVER value is required, or if a NEVER or MAYBE value is used
|
||||||
|
* where an ALWAYS value is required.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum When {
|
||||||
|
/** S is a subset of T */
|
||||||
|
ALWAYS,
|
||||||
|
/** nothing definitive is known about the relation between S and T */
|
||||||
|
UNKNOWN,
|
||||||
|
/** S intersection T is non empty and S - T is nonempty */
|
||||||
|
MAYBE,
|
||||||
|
/** S intersection T is empty */
|
||||||
|
NEVER;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
// 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.METHOD, ElementType.PARAMETER})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull(when = When.MAYBE)
|
||||||
|
@TypeQualifierNickname
|
||||||
|
public @interface Nullable {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: spr/NonNullApi.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.TypeQualifierDefault;
|
||||||
|
|
||||||
|
@Target(ElementType.CLASS)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Nonnull
|
||||||
|
@TypeQualifierDefault({ElementType.TYPE_USE})
|
||||||
|
public @interface NonNullApi {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import spr.*;
|
||||||
|
|
||||||
|
@NonNullApi
|
||||||
|
public class A {
|
||||||
|
public String field = null;
|
||||||
|
|
||||||
|
public String foo(String x, @Nullable CharSequence y) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String bar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public java.util.List<String> baz() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(a: A) {
|
||||||
|
a.foo("", null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
a.foo("", null).length
|
||||||
|
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||||
|
|
||||||
|
a.bar().length
|
||||||
|
a.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
|
||||||
|
|
||||||
|
a.field<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||||
|
a.field.length
|
||||||
|
|
||||||
|
a.baz()<!UNSAFE_CALL!>.<!>get(0)
|
||||||
|
a.baz()!!.get(0).get(0)
|
||||||
|
a.baz()!!.get(0)?.get(0)
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ a: A): kotlin.Unit
|
||||||
|
|
||||||
|
@spr.NonNullApi public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public final var field: kotlin.String
|
||||||
|
public open fun bar(): kotlin.String
|
||||||
|
@spr.Nullable public open fun baz(): kotlin.collections.(Mutable)List<kotlin.String!>?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun foo(/*0*/ x: kotlin.String, /*1*/ @spr.Nullable 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
|
||||||
|
}
|
||||||
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.test.util.DescriptorValidator
|
|||||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator
|
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator
|
||||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.RECURSIVE
|
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.RECURSIVE
|
||||||
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.RECURSIVE_ALL
|
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.RECURSIVE_ALL
|
||||||
|
import org.jetbrains.kotlin.utils.keysToMap
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -363,7 +364,15 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
|||||||
val comparator = RecursiveDescriptorComparator(createdAffectedPackagesConfiguration(testFiles, modules.values))
|
val comparator = RecursiveDescriptorComparator(createdAffectedPackagesConfiguration(testFiles, modules.values))
|
||||||
|
|
||||||
val isMultiModuleTest = modules.size != 1
|
val isMultiModuleTest = modules.size != 1
|
||||||
val rootPackageText = StringBuilder()
|
|
||||||
|
val packages =
|
||||||
|
(testFiles.flatMap {
|
||||||
|
InTextDirectivesUtils.findListWithPrefixes(it.expectedText, "// RENDER_PACKAGE:").map {
|
||||||
|
FqName(it.trim())
|
||||||
|
}
|
||||||
|
} + FqName.ROOT).toSet()
|
||||||
|
|
||||||
|
val textByPackage = packages.keysToMap { StringBuilder() }
|
||||||
|
|
||||||
val sortedModules = modules.keys.sortedWith(Comparator { x, y ->
|
val sortedModules = modules.keys.sortedWith(Comparator { x, y ->
|
||||||
when {
|
when {
|
||||||
@@ -375,32 +384,37 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
val module = sortedModules.iterator()
|
for ((packageName, packageText) in textByPackage.entries) {
|
||||||
while (module.hasNext()) {
|
val module = sortedModules.iterator()
|
||||||
val moduleDescriptor = modules[module.next()]!!
|
while (module.hasNext()) {
|
||||||
val aPackage = moduleDescriptor.getPackage(FqName.ROOT)
|
val moduleDescriptor = modules[module.next()]!!
|
||||||
assertFalse(aPackage.isEmpty())
|
|
||||||
|
|
||||||
if (isMultiModuleTest) {
|
val aPackage = moduleDescriptor.getPackage(packageName)
|
||||||
rootPackageText.append(String.format("// -- Module: %s --\n", moduleDescriptor.name))
|
assertFalse(aPackage.isEmpty())
|
||||||
}
|
|
||||||
|
|
||||||
val actualSerialized = comparator.serializeRecursively(aPackage)
|
if (isMultiModuleTest) {
|
||||||
rootPackageText.append(actualSerialized)
|
packageText.append(String.format("// -- Module: %s --\n", moduleDescriptor.name))
|
||||||
|
}
|
||||||
|
|
||||||
if (isMultiModuleTest && module.hasNext()) {
|
val actualSerialized = comparator.serializeRecursively(aPackage)
|
||||||
rootPackageText.append("\n\n")
|
packageText.append(actualSerialized)
|
||||||
|
|
||||||
|
if (isMultiModuleTest && module.hasNext()) {
|
||||||
|
packageText.append("\n\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val lineCount = StringUtil.getLineBreakCount(rootPackageText)
|
val allPackagesText = textByPackage.values.joinToString("\n")
|
||||||
|
|
||||||
|
val lineCount = StringUtil.getLineBreakCount(allPackagesText)
|
||||||
assert(lineCount < 1000) {
|
assert(lineCount < 1000) {
|
||||||
"Rendered descriptors of this test take up $lineCount lines. " +
|
"Rendered descriptors of this test take up $lineCount lines. " +
|
||||||
"Please ensure you don't render JRE contents to the .txt file. " +
|
"Please ensure you don't render JRE contents to the .txt file. " +
|
||||||
"Such tests are hard to maintain, take long time to execute and are subject to sudden unreviewed changes anyway."
|
"Such tests are hard to maintain, take long time to execute and are subject to sudden unreviewed changes anyway."
|
||||||
}
|
}
|
||||||
|
|
||||||
KotlinTestUtils.assertEqualsToFile(expectedFile, rootPackageText.toString())
|
KotlinTestUtils.assertEqualsToFile(expectedFile, allPackagesText)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createdAffectedPackagesConfiguration(
|
private fun createdAffectedPackagesConfiguration(
|
||||||
|
|||||||
+6
@@ -48,6 +48,12 @@ public class ForeignJava8AnnotationsTestGenerated extends AbstractForeignJava8An
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("springNullableWithTypeUse.kt")
|
||||||
|
public void testSpringNullableWithTypeUse() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotationsJava8/tests/springNullableWithTypeUse.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/typeEnhancement")
|
@TestMetadata("compiler/testData/foreignAnnotationsJava8/tests/typeEnhancement")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -89,4 +89,55 @@ public class ForeignAnnotationsTestGenerated extends AbstractForeignAnnotationsT
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/rxjava.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/rxjava.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class TypeQualifierDefault extends AbstractForeignAnnotationsTest {
|
||||||
|
public void testAllFilesPresentInTypeQualifierDefault() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/foreignAnnotations/tests/typeQualifierDefault"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fieldsAreNullable.kt")
|
||||||
|
public void testFieldsAreNullable() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault/fieldsAreNullable.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nullabilityFromOverridden.kt")
|
||||||
|
public void testNullabilityFromOverridden() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault/nullabilityFromOverridden.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overridingDefaultQualifier.kt")
|
||||||
|
public void testOverridingDefaultQualifier() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault/overridingDefaultQualifier.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parametersAreNonnullByDefault.kt")
|
||||||
|
public void testParametersAreNonnullByDefault() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault/parametersAreNonnullByDefault.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("parametersAreNonnullByDefaultPackage.kt")
|
||||||
|
public void testParametersAreNonnullByDefaultPackage() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault/parametersAreNonnullByDefaultPackage.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("springNullable.kt")
|
||||||
|
public void testSpringNullable() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault/springNullable.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("springNullablePackage.kt")
|
||||||
|
public void testSpringNullablePackage() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/foreignAnnotations/tests/typeQualifierDefault/springNullablePackage.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ class LoadJavaPackageAnnotationsTest : KtUsefulTestCase() {
|
|||||||
it.getMemberScope().getContributedClassifier(Name.identifier("A"), NoLookupLocation.FROM_TEST) != null
|
it.getMemberScope().getContributedClassifier(Name.identifier("A"), NoLookupLocation.FROM_TEST) != null
|
||||||
}.let { assertInstanceOf(it, LazyJavaPackageFragment::class.java) }
|
}.let { assertInstanceOf(it, LazyJavaPackageFragment::class.java) }
|
||||||
|
|
||||||
val annotation = packageFragmentDescriptor.getPackageAnnotations().findAnnotation(FqName("test.Ann"))
|
val annotation = packageFragmentDescriptor.annotations.findAnnotation(FqName("test.Ann"))
|
||||||
assertNotNull(annotation)
|
assertNotNull(annotation)
|
||||||
|
|
||||||
val singleAnnotation = packageFragmentDescriptor.getPackageAnnotations().singleOrNull()
|
val singleAnnotation = packageFragmentDescriptor.annotations.singleOrNull()
|
||||||
assertNotNull(singleAnnotation)
|
assertNotNull(singleAnnotation)
|
||||||
|
|
||||||
val annotationFqName = singleAnnotation!!.type.constructor.declarationDescriptor?.fqNameSafe
|
val annotationFqName = singleAnnotation!!.type.constructor.declarationDescriptor?.fqNameSafe
|
||||||
|
|||||||
+56
@@ -20,12 +20,16 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
|
||||||
private val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname")
|
private val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname")
|
||||||
private val TYPE_QUALIFIER_FQNAME = FqName("javax.annotation.meta.TypeQualifier")
|
private val TYPE_QUALIFIER_FQNAME = FqName("javax.annotation.meta.TypeQualifier")
|
||||||
|
private val TYPE_QUALIFIER_DEFAULT_FQNAME = FqName("javax.annotation.meta.TypeQualifierDefault")
|
||||||
|
|
||||||
class AnnotationTypeQualifierResolver(storageManager: StorageManager) {
|
class AnnotationTypeQualifierResolver(storageManager: StorageManager) {
|
||||||
private val resolvedNicknames =
|
private val resolvedNicknames =
|
||||||
@@ -49,6 +53,58 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager) {
|
|||||||
|
|
||||||
return resolveTypeQualifierNickname(annotationClass)
|
return resolveTypeQualifierNickname(annotationClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class QualifierApplicabilityType {
|
||||||
|
METHOD_RETURN_TYPE, VALUE_PARAMETER, FIELD, TYPE_USE
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeQualifierWithApplicability(
|
||||||
|
private val typeQualifier: AnnotationDescriptor,
|
||||||
|
private val applicability: Int
|
||||||
|
) {
|
||||||
|
private fun isApplicableTo(elementType: QualifierApplicabilityType) = (applicability and (1 shl elementType.ordinal)) != 0
|
||||||
|
|
||||||
|
operator fun component1() = typeQualifier
|
||||||
|
operator fun component2() = QualifierApplicabilityType.values().filter(this::isApplicableTo)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability? {
|
||||||
|
val typeQualifierDefaultAnnotatedClass =
|
||||||
|
annotationDescriptor.annotationClass?.takeIf { it.annotations.hasAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME) }
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
val elementTypesMask =
|
||||||
|
annotationDescriptor.annotationClass!!
|
||||||
|
.annotations.findAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME)!!
|
||||||
|
.allValueArguments
|
||||||
|
.flatMap { (parameter, argument) ->
|
||||||
|
if (parameter.name == JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME)
|
||||||
|
argument.mapConstantToQualifierApplicabilityTypes()
|
||||||
|
else
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
.fold(0) { acc: Int, applicabilityType -> acc or (1 shl applicabilityType.ordinal) }
|
||||||
|
|
||||||
|
val typeQualifier =
|
||||||
|
typeQualifierDefaultAnnotatedClass.annotations.firstNotNullResult(this::resolveTypeQualifierAnnotation)
|
||||||
|
?: return null
|
||||||
|
return TypeQualifierWithApplicability(typeQualifier, elementTypesMask)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConstantValue<*>.mapConstantToQualifierApplicabilityTypes(): List<QualifierApplicabilityType> =
|
||||||
|
when (this) {
|
||||||
|
is ArrayValue -> value.flatMap { it.mapConstantToQualifierApplicabilityTypes() }
|
||||||
|
is EnumValue -> listOfNotNull(
|
||||||
|
when (value.name.identifier) {
|
||||||
|
"METHOD" -> QualifierApplicabilityType.METHOD_RETURN_TYPE
|
||||||
|
"FIELD" -> QualifierApplicabilityType.FIELD
|
||||||
|
"PARAMETER" -> QualifierApplicabilityType.VALUE_PARAMETER
|
||||||
|
"TYPE_USE" -> QualifierApplicabilityType.TYPE_USE
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else -> emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val ClassDescriptor.isAnnotatedWithTypeQualifier: Boolean
|
private val ClassDescriptor.isAnnotatedWithTypeQualifier: Boolean
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ class LazyJavaPackageFragmentProvider(
|
|||||||
components: JavaResolverComponents
|
components: JavaResolverComponents
|
||||||
) : PackageFragmentProvider {
|
) : PackageFragmentProvider {
|
||||||
|
|
||||||
private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY)
|
private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null }
|
||||||
|
|
||||||
private val packageFragments: MemoizedFunctionToNullable<FqName, LazyJavaPackageFragment> =
|
private val packageFragments: MemoizedFunctionToNullable<FqName, LazyJavaPackageFragment> =
|
||||||
c.storageManager.createMemoizedFunctionWithNullableValues {
|
c.storageManager.createMemoizedFunctionWithNullableValues {
|
||||||
|
|||||||
@@ -17,10 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.load.java.lazy
|
package org.jetbrains.kotlin.load.java.lazy
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
|
||||||
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
|
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
|
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
|
||||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||||
@@ -28,11 +26,14 @@ import org.jetbrains.kotlin.load.java.components.*
|
|||||||
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
|
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
|
||||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
|
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
|
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
|
||||||
|
import org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeQualifiers
|
||||||
|
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
||||||
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
|
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class JavaResolverComponents(
|
class JavaResolverComponents(
|
||||||
val storageManager: StorageManager,
|
val storageManager: StorageManager,
|
||||||
@@ -66,10 +67,33 @@ class JavaResolverComponents(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
class LazyJavaResolverContext(
|
private typealias QualifierByApplicabilityType = EnumMap<AnnotationTypeQualifierResolver.QualifierApplicabilityType, NullabilityQualifier?>
|
||||||
val components: JavaResolverComponents,
|
|
||||||
val typeParameterResolver: TypeParameterResolver
|
class JavaTypeQualifiersByElementType(
|
||||||
|
internal val nullabilityQualifiers: QualifierByApplicabilityType
|
||||||
) {
|
) {
|
||||||
|
operator fun get(
|
||||||
|
applicabilityType: AnnotationTypeQualifierResolver.QualifierApplicabilityType
|
||||||
|
): JavaTypeQualifiers? =
|
||||||
|
(
|
||||||
|
nullabilityQualifiers[applicabilityType]
|
||||||
|
?: nullabilityQualifiers[AnnotationTypeQualifierResolver.QualifierApplicabilityType.TYPE_USE]
|
||||||
|
)?.let { JavaTypeQualifiers(it, null, isNotNullTypeParameter = false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
class LazyJavaResolverContext internal constructor(
|
||||||
|
val components: JavaResolverComponents,
|
||||||
|
val typeParameterResolver: TypeParameterResolver,
|
||||||
|
internal val delegateForDefaultTypeQualifiers: Lazy<JavaTypeQualifiersByElementType?>
|
||||||
|
) {
|
||||||
|
constructor(
|
||||||
|
components: JavaResolverComponents,
|
||||||
|
typeParameterResolver: TypeParameterResolver,
|
||||||
|
typeQualifiersComputation: () -> JavaTypeQualifiersByElementType?
|
||||||
|
) : this(components, typeParameterResolver, lazy(LazyThreadSafetyMode.NONE, typeQualifiersComputation))
|
||||||
|
|
||||||
|
val defaultTypeQualifiers: JavaTypeQualifiersByElementType? by delegateForDefaultTypeQualifiers
|
||||||
|
|
||||||
val typeResolver = JavaTypeResolver(this, typeParameterResolver)
|
val typeResolver = JavaTypeResolver(this, typeParameterResolver)
|
||||||
|
|
||||||
val storageManager: StorageManager
|
val storageManager: StorageManager
|
||||||
@@ -80,14 +104,59 @@ class LazyJavaResolverContext(
|
|||||||
|
|
||||||
fun LazyJavaResolverContext.child(
|
fun LazyJavaResolverContext.child(
|
||||||
typeParameterResolver: TypeParameterResolver
|
typeParameterResolver: TypeParameterResolver
|
||||||
) = LazyJavaResolverContext(components, typeParameterResolver)
|
) = LazyJavaResolverContext(components, typeParameterResolver, delegateForDefaultTypeQualifiers)
|
||||||
|
|
||||||
|
fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers(
|
||||||
|
additionalAnnotations: Annotations
|
||||||
|
): JavaTypeQualifiersByElementType? {
|
||||||
|
val typeQualifierDefaults =
|
||||||
|
additionalAnnotations.mapNotNull(components.annotationTypeQualifierResolver::resolveTypeQualifierDefaultAnnotation)
|
||||||
|
|
||||||
|
if (typeQualifierDefaults.isEmpty()) return defaultTypeQualifiers
|
||||||
|
|
||||||
|
val nullabilityQualifiers =
|
||||||
|
defaultTypeQualifiers?.nullabilityQualifiers?.let(::QualifierByApplicabilityType)
|
||||||
|
?: QualifierByApplicabilityType(AnnotationTypeQualifierResolver.QualifierApplicabilityType::class.java)
|
||||||
|
|
||||||
|
var wasUpdate = false
|
||||||
|
for ((typeQualifier, applicableTo) in typeQualifierDefaults) {
|
||||||
|
val nullability = components.signatureEnhancement.extractNullability(typeQualifier) ?: continue
|
||||||
|
for (applicabilityType in applicableTo) {
|
||||||
|
nullabilityQualifiers[applicabilityType] = nullability
|
||||||
|
wasUpdate = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(nullabilityQualifiers)
|
||||||
|
}
|
||||||
|
|
||||||
fun LazyJavaResolverContext.replaceComponents(
|
fun LazyJavaResolverContext.replaceComponents(
|
||||||
components: JavaResolverComponents
|
components: JavaResolverComponents
|
||||||
) = LazyJavaResolverContext(components, typeParameterResolver)
|
) = LazyJavaResolverContext(components, typeParameterResolver, delegateForDefaultTypeQualifiers)
|
||||||
|
|
||||||
fun LazyJavaResolverContext.child(
|
private fun LazyJavaResolverContext.child(
|
||||||
|
containingDeclaration: DeclarationDescriptor,
|
||||||
|
typeParameterOwner: JavaTypeParameterListOwner?,
|
||||||
|
typeParametersIndexOffset: Int = 0,
|
||||||
|
delegateForTypeQualifiers: Lazy<JavaTypeQualifiersByElementType?>
|
||||||
|
) = LazyJavaResolverContext(
|
||||||
|
components,
|
||||||
|
typeParameterOwner?.let { LazyJavaTypeParameterResolver(this, containingDeclaration, it, typeParametersIndexOffset) }
|
||||||
|
?: typeParameterResolver,
|
||||||
|
delegateForTypeQualifiers
|
||||||
|
)
|
||||||
|
|
||||||
|
fun LazyJavaResolverContext.childForMethod(
|
||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: DeclarationDescriptor,
|
||||||
typeParameterOwner: JavaTypeParameterListOwner,
|
typeParameterOwner: JavaTypeParameterListOwner,
|
||||||
typeParametersIndexOffset: Int = 0
|
typeParametersIndexOffset: Int = 0
|
||||||
) = this.child(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameterOwner, typeParametersIndexOffset))
|
) = child(containingDeclaration, typeParameterOwner, typeParametersIndexOffset, delegateForDefaultTypeQualifiers)
|
||||||
|
|
||||||
|
fun LazyJavaResolverContext.childForClassOrPackage(
|
||||||
|
containingDeclaration: ClassOrPackageFragmentDescriptor,
|
||||||
|
typeParameterOwner: JavaTypeParameterListOwner? = null,
|
||||||
|
typeParametersIndexOffset: Int = 0
|
||||||
|
) = child(
|
||||||
|
containingDeclaration, typeParameterOwner, typeParametersIndexOffset,
|
||||||
|
lazy(LazyThreadSafetyMode.NONE) { computeNewDefaultTypeQualifiers(containingDeclaration.annotations) }
|
||||||
|
)
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.load.java.components.JavaResolverCache
|
|||||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||||
import org.jetbrains.kotlin.load.java.lazy.child
|
import org.jetbrains.kotlin.load.java.lazy.childForClassOrPackage
|
||||||
import org.jetbrains.kotlin.load.java.lazy.replaceComponents
|
import org.jetbrains.kotlin.load.java.lazy.replaceComponents
|
||||||
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
||||||
@@ -64,7 +64,7 @@ class LazyJavaClassDescriptor(
|
|||||||
private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString")
|
private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val c: LazyJavaResolverContext = outerContext.child(this, jClass)
|
private val c: LazyJavaResolverContext = outerContext.childForClassOrPackage(this, jClass)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
c.components.javaResolverCache.recordClass(jClass, this)
|
c.components.javaResolverCache.recordClass(jClass, this)
|
||||||
|
|||||||
+4
-3
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
|||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.copyValueParameters
|
import org.jetbrains.kotlin.load.java.descriptors.copyValueParameters
|
||||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||||
import org.jetbrains.kotlin.load.java.lazy.child
|
import org.jetbrains.kotlin.load.java.lazy.childForMethod
|
||||||
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
|
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
|
||||||
@@ -86,6 +86,7 @@ class LazyJavaClassMemberScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.components.signatureEnhancement.enhanceSignatures(
|
c.components.signatureEnhancement.enhanceSignatures(
|
||||||
|
c,
|
||||||
result.ifEmpty { listOfNotNull(createDefaultConstructor()) }
|
result.ifEmpty { listOfNotNull(createDefaultConstructor()) }
|
||||||
).toList()
|
).toList()
|
||||||
}
|
}
|
||||||
@@ -424,7 +425,7 @@ class LazyJavaClassMemberScope(
|
|||||||
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, Annotations.EMPTY)
|
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, Annotations.EMPTY)
|
||||||
propertyDescriptor.initialize(getter, null)
|
propertyDescriptor.initialize(getter, null)
|
||||||
|
|
||||||
val returnType = givenType ?: computeMethodReturnType(method, annotations, c.child(propertyDescriptor, method))
|
val returnType = givenType ?: computeMethodReturnType(method, annotations, c.childForMethod(propertyDescriptor, method))
|
||||||
propertyDescriptor.setType(returnType, listOf(), getDispatchReceiverParameter(), null as KotlinType?)
|
propertyDescriptor.setType(returnType, listOf(), getDispatchReceiverParameter(), null as KotlinType?)
|
||||||
getter.initialize(returnType)
|
getter.initialize(returnType)
|
||||||
|
|
||||||
@@ -511,7 +512,7 @@ class LazyJavaClassMemberScope(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
val c = c.child(constructorDescriptor, constructor, typeParametersIndexOffset = classDescriptor.declaredTypeParameters.size)
|
val c = c.childForMethod(constructorDescriptor, constructor, typeParametersIndexOffset = classDescriptor.declaredTypeParameters.size)
|
||||||
val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.valueParameters)
|
val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.valueParameters)
|
||||||
val constructorTypeParameters =
|
val constructorTypeParameters =
|
||||||
classDescriptor.declaredTypeParameters +
|
classDescriptor.declaredTypeParameters +
|
||||||
|
|||||||
+6
-6
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.childForClassOrPackage
|
||||||
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaPackage
|
import org.jetbrains.kotlin.load.java.structure.JavaPackage
|
||||||
@@ -31,9 +32,11 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.storage.getValue
|
import org.jetbrains.kotlin.storage.getValue
|
||||||
|
|
||||||
class LazyJavaPackageFragment(
|
class LazyJavaPackageFragment(
|
||||||
private val c: LazyJavaResolverContext,
|
outerContext: LazyJavaResolverContext,
|
||||||
private val jPackage: JavaPackage
|
private val jPackage: JavaPackage
|
||||||
) : PackageFragmentDescriptorImpl(c.module, jPackage.fqName) {
|
) : PackageFragmentDescriptorImpl(outerContext.module, jPackage.fqName) {
|
||||||
|
private val c = outerContext.childForClassOrPackage(this)
|
||||||
|
|
||||||
internal val binaryClasses by c.storageManager.createLazyValue {
|
internal val binaryClasses by c.storageManager.createLazyValue {
|
||||||
c.components.packageMapper.findPackageParts(fqName.asString()).mapNotNull { partName ->
|
c.components.packageMapper.findPackageParts(fqName.asString()).mapNotNull { partName ->
|
||||||
val classId = ClassId(fqName, Name.identifier(partName))
|
val classId = ClassId(fqName, Name.identifier(partName))
|
||||||
@@ -49,10 +52,7 @@ class LazyJavaPackageFragment(
|
|||||||
onRecursiveCall = listOf()
|
onRecursiveCall = listOf()
|
||||||
)
|
)
|
||||||
|
|
||||||
private val packageAnnotations = c.resolveAnnotations(jPackage)
|
override val annotations = c.resolveAnnotations(jPackage)
|
||||||
|
|
||||||
// Test only method
|
|
||||||
fun getPackageAnnotations() = packageAnnotations
|
|
||||||
|
|
||||||
internal fun getSubPackageFqNames(): List<FqName> = subPackages()
|
internal fun getSubPackageFqNames(): List<FqName> = subPackages()
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.load.java.components.TypeUsage
|
|||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||||
import org.jetbrains.kotlin.load.java.lazy.child
|
import org.jetbrains.kotlin.load.java.lazy.childForMethod
|
||||||
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeAttributes
|
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeAttributes
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
|
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
|
||||||
@@ -87,7 +87,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
|
|||||||
|
|
||||||
computeNonDeclaredFunctions(result, name)
|
computeNonDeclaredFunctions(result, name)
|
||||||
|
|
||||||
c.components.signatureEnhancement.enhanceSignatures(result).toList()
|
c.components.signatureEnhancement.enhanceSignatures(c, result).toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
open protected fun JavaMethodDescriptor.isVisibleAsFunction() = true
|
open protected fun JavaMethodDescriptor.isVisibleAsFunction() = true
|
||||||
@@ -114,7 +114,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
|
|||||||
ownerDescriptor, annotations, method.name, c.components.sourceElementFactory.source(method)
|
ownerDescriptor, annotations, method.name, c.components.sourceElementFactory.source(method)
|
||||||
)
|
)
|
||||||
|
|
||||||
val c = c.child(functionDescriptorImpl, method)
|
val c = c.childForMethod(functionDescriptorImpl, method)
|
||||||
|
|
||||||
val methodTypeParameters = method.typeParameters.map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! }
|
val methodTypeParameters = method.typeParameters.map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! }
|
||||||
val valueParameters = resolveValueParameters(c, functionDescriptorImpl, method.valueParameters)
|
val valueParameters = resolveValueParameters(c, functionDescriptorImpl, method.valueParameters)
|
||||||
@@ -246,7 +246,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
|
|||||||
if (DescriptorUtils.isAnnotationClass(ownerDescriptor))
|
if (DescriptorUtils.isAnnotationClass(ownerDescriptor))
|
||||||
properties.toList()
|
properties.toList()
|
||||||
else
|
else
|
||||||
c.components.signatureEnhancement.enhanceSignatures(properties).toList()
|
c.components.signatureEnhancement.enhanceSignatures(c, properties).toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveProperty(field: JavaField): PropertyDescriptor {
|
private fun resolveProperty(field: JavaField): PropertyDescriptor {
|
||||||
|
|||||||
+64
-31
@@ -19,12 +19,17 @@ package org.jetbrains.kotlin.load.java.typeEnhancement
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
|
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.*
|
import org.jetbrains.kotlin.load.java.*
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.computeNewDefaultTypeQualifiers
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
||||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||||
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
|
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -36,17 +41,40 @@ import org.jetbrains.kotlin.types.asFlexibleType
|
|||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.types.isFlexible
|
import org.jetbrains.kotlin.types.isFlexible
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class SignatureEnhancement(private val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver) {
|
class SignatureEnhancement(private val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver) {
|
||||||
fun <D : CallableMemberDescriptor> enhanceSignatures(platformSignatures: Collection<D>): Collection<D> {
|
|
||||||
|
fun extractNullability(annotationDescriptor: AnnotationDescriptor): NullabilityQualifier? {
|
||||||
|
when (annotationDescriptor.annotationClass?.fqNameSafe) {
|
||||||
|
in NULLABLE_ANNOTATIONS -> return NullabilityQualifier.NULLABLE
|
||||||
|
in NOT_NULL_ANNOTATIONS -> return NullabilityQualifier.NOT_NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
val typeQualifier =
|
||||||
|
annotationTypeQualifierResolver
|
||||||
|
.resolveTypeQualifierAnnotation(annotationDescriptor)
|
||||||
|
?.takeIf { it.annotationClass?.fqNameSafe == JAVAX_NONNULL_ANNOTATION }
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
return typeQualifier.allValueArguments.values.singleOrNull()?.value?.let {
|
||||||
|
enumEntryDescriptor ->
|
||||||
|
if (enumEntryDescriptor !is ClassDescriptor) return@let null
|
||||||
|
if (enumEntryDescriptor.name.asString() == "ALWAYS") NullabilityQualifier.NOT_NULL else NullabilityQualifier.NULLABLE
|
||||||
|
} ?: NullabilityQualifier.NOT_NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun <D : CallableMemberDescriptor> enhanceSignatures(c: LazyJavaResolverContext, platformSignatures: Collection<D>): Collection<D> {
|
||||||
return platformSignatures.map {
|
return platformSignatures.map {
|
||||||
it.enhanceSignature()
|
it.enhanceSignature(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : CallableMemberDescriptor> D.enhanceSignature(): D {
|
private fun <D : CallableMemberDescriptor> D.enhanceSignature(c: LazyJavaResolverContext): D {
|
||||||
|
val outerScopeQualifiers = c.computeNewDefaultTypeQualifiers(annotations)
|
||||||
// TODO type parameters
|
// TODO type parameters
|
||||||
// TODO use new type parameters while enhancing other types
|
// TODO use new type parameters while enhancing other types
|
||||||
// TODO Propagation into generic type arguments
|
// TODO Propagation into generic type arguments
|
||||||
@@ -62,7 +90,10 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
|||||||
typeContainer =
|
typeContainer =
|
||||||
this.safeAs<FunctionDescriptor>()
|
this.safeAs<FunctionDescriptor>()
|
||||||
?.getUserData(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER),
|
?.getUserData(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER),
|
||||||
isCovariant = false
|
isCovariant = false,
|
||||||
|
defaultTopLevelQualifiers =
|
||||||
|
outerScopeQualifiers
|
||||||
|
?.get(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER)
|
||||||
) { it.extensionReceiverParameter!!.type }.enhance()
|
) { it.extensionReceiverParameter!!.type }.enhance()
|
||||||
else null
|
else null
|
||||||
|
|
||||||
@@ -81,12 +112,28 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
|||||||
|
|
||||||
val valueParameterEnhancements = valueParameters.map {
|
val valueParameterEnhancements = valueParameters.map {
|
||||||
p ->
|
p ->
|
||||||
parts(typeContainer = p, isCovariant = false) { it.valueParameters[p.index].type }
|
parts(
|
||||||
|
typeContainer = p, isCovariant = false,
|
||||||
|
defaultTopLevelQualifiers =
|
||||||
|
outerScopeQualifiers
|
||||||
|
?.get(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER)
|
||||||
|
) { it.valueParameters[p.index].type }
|
||||||
.enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
|
.enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
|
||||||
}
|
}
|
||||||
|
|
||||||
val returnTypeEnhancement =
|
val returnTypeEnhancement =
|
||||||
parts(typeContainer = this, isCovariant = true) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
|
parts(
|
||||||
|
typeContainer = this, isCovariant = true,
|
||||||
|
defaultTopLevelQualifiers =
|
||||||
|
outerScopeQualifiers?.get(
|
||||||
|
if (this.safeAs<PropertyDescriptor>()?.isJavaField == true)
|
||||||
|
AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD
|
||||||
|
else
|
||||||
|
AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
|
||||||
|
|
||||||
if ((receiverTypeEnhancement?.wereChanges ?: false)
|
if ((receiverTypeEnhancement?.wereChanges ?: false)
|
||||||
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) {
|
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) {
|
||||||
@@ -101,7 +148,8 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
|||||||
private val typeContainer: Annotated?,
|
private val typeContainer: Annotated?,
|
||||||
private val fromOverride: KotlinType,
|
private val fromOverride: KotlinType,
|
||||||
private val fromOverridden: Collection<KotlinType>,
|
private val fromOverridden: Collection<KotlinType>,
|
||||||
private val isCovariant: Boolean
|
private val isCovariant: Boolean,
|
||||||
|
private val defaultTopLevelQualifiers: JavaTypeQualifiers?
|
||||||
) {
|
) {
|
||||||
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
|
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
|
||||||
val qualifiers = computeIndexedQualifiersForOverride()
|
val qualifiers = computeIndexedQualifiersForOverride()
|
||||||
@@ -152,7 +200,10 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
|||||||
|
|
||||||
fun <T: Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null
|
fun <T: Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null
|
||||||
|
|
||||||
val nullability = composedAnnotation.extractNullability()
|
val defaultTypeQualifier = defaultTopLevelQualifiers?.takeIf { isHeadTypeConstructor }
|
||||||
|
val nullability =
|
||||||
|
composedAnnotation.extractNullability()
|
||||||
|
?: defaultTypeQualifier?.nullability
|
||||||
|
|
||||||
return JavaTypeQualifiers(
|
return JavaTypeQualifiers(
|
||||||
nullability,
|
nullability,
|
||||||
@@ -168,28 +219,8 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Annotations.extractNullability(): NullabilityQualifier? {
|
private fun Annotations.extractNullability(): NullabilityQualifier? =
|
||||||
for (annotationDescriptor in this) {
|
this.firstNotNullResult(this@SignatureEnhancement::extractNullability)
|
||||||
when (annotationDescriptor.annotationClass?.fqNameSafe) {
|
|
||||||
in NULLABLE_ANNOTATIONS -> return NullabilityQualifier.NULLABLE
|
|
||||||
in NOT_NULL_ANNOTATIONS -> return NullabilityQualifier.NOT_NULL
|
|
||||||
}
|
|
||||||
|
|
||||||
val typeQualifier =
|
|
||||||
annotationTypeQualifierResolver
|
|
||||||
.resolveTypeQualifierAnnotation(annotationDescriptor)
|
|
||||||
?.takeIf { it.annotationClass?.fqNameSafe == JAVAX_NONNULL_ANNOTATION }
|
|
||||||
?: continue
|
|
||||||
|
|
||||||
return typeQualifier.allValueArguments.values.singleOrNull()?.value?.let {
|
|
||||||
enumEntryDescriptor ->
|
|
||||||
if (enumEntryDescriptor !is ClassDescriptor) return@let null
|
|
||||||
if (enumEntryDescriptor.name.asString() == "ALWAYS") NullabilityQualifier.NOT_NULL else NullabilityQualifier.NULLABLE
|
|
||||||
} ?: NullabilityQualifier.NOT_NULL
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers {
|
private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers {
|
||||||
fun KotlinType.toIndexed(): List<KotlinType> {
|
fun KotlinType.toIndexed(): List<KotlinType> {
|
||||||
@@ -292,6 +323,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
|||||||
private fun <D : CallableMemberDescriptor> D.parts(
|
private fun <D : CallableMemberDescriptor> D.parts(
|
||||||
typeContainer: Annotated?,
|
typeContainer: Annotated?,
|
||||||
isCovariant: Boolean,
|
isCovariant: Boolean,
|
||||||
|
defaultTopLevelQualifiers: JavaTypeQualifiers?,
|
||||||
collector: (D) -> KotlinType
|
collector: (D) -> KotlinType
|
||||||
): SignatureParts {
|
): SignatureParts {
|
||||||
return SignatureParts(
|
return SignatureParts(
|
||||||
@@ -301,7 +333,8 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
collector(it as D)
|
collector(it as D)
|
||||||
},
|
},
|
||||||
isCovariant
|
isCovariant,
|
||||||
|
defaultTopLevelQualifiers
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -66,7 +66,7 @@ public class JdkAndMockLibraryProjectDescriptor extends KotlinLightProjectDescri
|
|||||||
File libraryJar =
|
File libraryJar =
|
||||||
isJsLibrary
|
isJsLibrary
|
||||||
? MockLibraryUtil.compileJsLibraryToJar(sourcesPath, LIBRARY_NAME, withSources)
|
? MockLibraryUtil.compileJsLibraryToJar(sourcesPath, LIBRARY_NAME, withSources)
|
||||||
: MockLibraryUtil.compileJvmLibraryToJar(sourcesPath, LIBRARY_NAME, withSources, extraOptions, classpath);
|
: MockLibraryUtil.compileJvmLibraryToJar(sourcesPath, LIBRARY_NAME, withSources, true, extraOptions, classpath);
|
||||||
String jarUrl = getJarUrl(libraryJar);
|
String jarUrl = getJarUrl(libraryJar);
|
||||||
|
|
||||||
Library.ModifiableModel libraryModel = model.getModuleLibraryTable().getModifiableModel().createLibrary(LIBRARY_NAME).getModifiableModel();
|
Library.ModifiableModel libraryModel = model.getModuleLibraryTable().getModifiableModel().createLibrary(LIBRARY_NAME).getModifiableModel();
|
||||||
|
|||||||
Reference in New Issue
Block a user