K2: Fix Java enhancement when jsr305.jar is not in classpath
In that case, when loading Java, we just remember the name of `@Nonnull` argument (javax.annotation.meta.When), and then use it during enhancement ^KT-56656 Fixed
This commit is contained in:
committed by
Space Team
parent
955b8e1490
commit
644391a8e0
+3
-6
@@ -10,11 +10,9 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.collectEnumEntries
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildFromMissingDependenciesNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
@@ -285,9 +283,8 @@ abstract class AbstractAnnotationDeserializer(
|
||||
name = entryName
|
||||
resolvedSymbol = it.symbol
|
||||
}
|
||||
} ?: buildErrorNamedReference {
|
||||
diagnostic =
|
||||
ConeSimpleDiagnostic("Strange deserialized enum value: $classId.$entryName", DiagnosticKind.DeserializationError)
|
||||
} ?: buildFromMissingDependenciesNamedReference {
|
||||
name = entryName
|
||||
}
|
||||
if (enumEntrySymbol != null) {
|
||||
typeRef = enumEntrySymbol.returnTypeRef
|
||||
|
||||
+13
-1
@@ -12,8 +12,11 @@ import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.convertAnnotationsToFir
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.references.FirFromMissingDependenciesNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.load.java.AbstractAnnotationTypeQualifierResolver
|
||||
import org.jetbrains.kotlin.load.java.JavaModuleAnnotationsProvider
|
||||
import org.jetbrains.kotlin.load.java.JavaTypeEnhancementState
|
||||
@@ -48,7 +51,16 @@ class FirAnnotationTypeQualifierResolver(
|
||||
when (this) {
|
||||
is FirArrayOfCall -> arguments.flatMap { it.toEnumNames() }
|
||||
is FirVarargArgumentsExpression -> arguments.flatMap { it.toEnumNames() }
|
||||
else -> listOfNotNull(toResolvedCallableSymbol()?.callableId?.callableName?.asString())
|
||||
else -> {
|
||||
val name = when (val reference = toReference()) {
|
||||
is FirResolvedNamedReference ->
|
||||
(reference.resolvedSymbol as? FirCallableSymbol<*>)?.callableId?.callableName?.asString()
|
||||
is FirFromMissingDependenciesNamedReference -> reference.name.asString()
|
||||
else -> null
|
||||
}
|
||||
|
||||
listOfNotNull(name)
|
||||
}
|
||||
}
|
||||
|
||||
fun extractDefaultQualifiers(firClass: FirRegularClass): JavaTypeQualifiersByElementType? {
|
||||
|
||||
@@ -13,10 +13,15 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.buildUnaryArgumentList
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||
import org.jetbrains.kotlin.fir.java.declarations.buildJavaValueParameter
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildFromMissingDependenciesNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
||||
@@ -133,7 +138,7 @@ private val JAVA_TARGETS_TO_KOTLIN = mapOf(
|
||||
|
||||
private fun buildEnumCall(session: FirSession, classId: ClassId?, entryName: Name?): FirPropertyAccessExpression {
|
||||
return buildPropertyAccessExpression {
|
||||
val calleeReference = if (classId != null && entryName != null) {
|
||||
val resolvedCalleeReference: FirResolvedNamedReference? = if (classId != null && entryName != null) {
|
||||
session.symbolProvider.getClassDeclaredPropertySymbols(classId, entryName)
|
||||
.firstOrNull()?.let { propertySymbol ->
|
||||
buildResolvedNamedReference {
|
||||
@@ -144,9 +149,18 @@ private fun buildEnumCall(session: FirSession, classId: ClassId?, entryName: Nam
|
||||
} else {
|
||||
null
|
||||
}
|
||||
this.calleeReference = calleeReference ?: buildErrorNamedReference {
|
||||
diagnostic = ConeSimpleDiagnostic("Strange Java enum value: $classId.$entryName", DiagnosticKind.Java)
|
||||
}
|
||||
|
||||
this.calleeReference =
|
||||
resolvedCalleeReference
|
||||
// if we haven't found the containing class for the entry in the classpath, let's just remember its name, so we could use it,
|
||||
// e.g. during Java enhancement
|
||||
?: entryName?.let {
|
||||
buildFromMissingDependenciesNamedReference {
|
||||
name = entryName
|
||||
}
|
||||
} ?: buildErrorNamedReference {
|
||||
diagnostic = ConeSimpleDiagnostic("Enum entry name is null in Java for $classId", DiagnosticKind.Java)
|
||||
}
|
||||
|
||||
if (classId != null) {
|
||||
this.typeRef = buildResolvedTypeRef {
|
||||
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
// SOURCE_RETENTION_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT: strict
|
||||
|
||||
// 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.TYPE, ElementType.TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.TYPE_USE})
|
||||
public @interface NonNullApi {
|
||||
}
|
||||
|
||||
// FILE: spr/NullableApi.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;
|
||||
import javax.annotation.meta.When;
|
||||
|
||||
@Target({ElementType.TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull(when = When.MAYBE)
|
||||
@TypeQualifierDefault({ElementType.TYPE_USE})
|
||||
public @interface NullableApi {
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import spr.*;
|
||||
import java.util.*;
|
||||
|
||||
@NonNullApi
|
||||
public class A {
|
||||
public String foo(String x) { return ""; }
|
||||
public @NullableApi String bar(@NullableApi String y) { return ""; }
|
||||
public @NullableApi List<String> baz1() { return null; }
|
||||
public List<@NullableApi String> baz2() { return null; }
|
||||
public @NullableApi List<@NonNullApi String> baz3() { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a: A) {
|
||||
a.foo("").length
|
||||
a.foo(null)?.length
|
||||
|
||||
a.bar("").length
|
||||
a.bar(null)?.length
|
||||
|
||||
a.baz1().get(0).length
|
||||
a.baz1()!!.get(0).length
|
||||
a.baz1()!!.get(0)?.length
|
||||
|
||||
a.baz2().get(0).length
|
||||
a.baz2()!!.get(0).length
|
||||
a.baz2()!!.get(0)?.length
|
||||
|
||||
a.baz3().get(0).length
|
||||
a.baz3()!!.get(0).length
|
||||
a.baz3()!!.get(0)?.length
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
// SOURCE_RETENTION_ANNOTATIONS
|
||||
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
// SOURCE_RETENTION_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT: strict
|
||||
|
||||
// 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.TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.TYPE_USE})
|
||||
public @interface NonNullApi {
|
||||
}
|
||||
|
||||
// FILE: spr/NullableApi.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;
|
||||
import javax.annotation.meta.When;
|
||||
|
||||
@Target({ElementType.TYPE, ElementType.TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull(when = When.MAYBE)
|
||||
@TypeQualifierDefault({ElementType.TYPE_USE})
|
||||
public @interface NullableApi {
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import spr.*;
|
||||
import java.util.*;
|
||||
|
||||
@NonNullApi
|
||||
public class A {
|
||||
public String foo(String x) { return ""; }
|
||||
public @NullableApi String bar(@NullableApi String y) { return ""; }
|
||||
public @NullableApi List<String> baz1() { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a: A) {
|
||||
a.foo("").length
|
||||
a.foo(null)?.length
|
||||
|
||||
a.bar("").length
|
||||
a.bar(null)?.length
|
||||
|
||||
a.baz1().get(0).length
|
||||
a.baz1()!!.get(0).length
|
||||
a.baz1()!!.get(0)?.length
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
// SOURCE_RETENTION_ANNOTATIONS
|
||||
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// JSR305_GLOBAL_REPORT: strict
|
||||
|
||||
// FILE: spr/Nullable.java
|
||||
package spr;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierNickname;
|
||||
import javax.annotation.meta.When;
|
||||
|
||||
@Target({ElementType.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.TYPE)
|
||||
@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)?.length
|
||||
a.foo("", null).length
|
||||
a.foo(null, "").length
|
||||
|
||||
a.bar().length
|
||||
a.bar()!!.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)
|
||||
}
|
||||
compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jsr305/springNullableWithTypeUse.kt
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// JSR305_GLOBAL_REPORT: strict
|
||||
|
||||
|
||||
Vendored
+6
-6
@@ -78,15 +78,15 @@ import test.L
|
||||
fun main(a: test.A, l: L<Map<String, Int>, Int?>, l1: L<Map<String, Int>, Int>) {
|
||||
a.foo(l)
|
||||
a.foo(<!ARGUMENT_TYPE_MISMATCH!>l <!UNCHECKED_CAST!>as L<Map<String, Int>, Int><!><!>)
|
||||
a.foo(l <!UNCHECKED_CAST!>as L<Map<String, Int?>, Int?><!>)
|
||||
a.foo(<!ARGUMENT_TYPE_MISMATCH!>l <!UNCHECKED_CAST!>as L<Map<String, Int?>, Int?><!><!>)
|
||||
|
||||
a.bar(l1)
|
||||
a.bar(l1 <!UNCHECKED_CAST!>as L<Map<String, Int>, Int?><!>)
|
||||
a.bar(<!ARGUMENT_TYPE_MISMATCH!>l1 <!UNCHECKED_CAST!>as L<Map<String, Int>, Int?><!><!>)
|
||||
|
||||
a.baz1().t().containsKey("")
|
||||
a.baz1().t().containsKey(null)
|
||||
a.baz1().t().<!TYPE_INFERENCE_ONLY_INPUT_TYPES_ERROR!>containsKey<!>(null)
|
||||
a.baz1().t().containsValue(1)
|
||||
a.baz1().t().containsValue(null)
|
||||
a.baz1().t().<!TYPE_INFERENCE_ONLY_INPUT_TYPES_ERROR!>containsValue<!>(null)
|
||||
a.baz1().s().hashCode()
|
||||
|
||||
a.baz1().setT(l.t())
|
||||
@@ -100,8 +100,8 @@ fun main(a: test.A, l: L<Map<String, Int>, Int?>, l1: L<Map<String, Int>, Int>)
|
||||
a.baz2().s().hashCode()
|
||||
|
||||
a.baz3().t().containsKey("")
|
||||
a.baz3().t().containsKey(null)
|
||||
a.baz3().t().<!TYPE_INFERENCE_ONLY_INPUT_TYPES_ERROR!>containsKey<!>(null)
|
||||
a.baz3().t().containsValue(1)
|
||||
a.baz3().t().containsValue(null)
|
||||
a.baz3().t().<!TYPE_INFERENCE_ONLY_INPUT_TYPES_ERROR!>containsValue<!>(null)
|
||||
a.baz3().s().hashCode()
|
||||
}
|
||||
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
// SOURCE_RETENTION_ANNOTATIONS
|
||||
// JSR305_GLOBAL_REPORT: strict
|
||||
|
||||
// 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.TYPE, ElementType.TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull
|
||||
@TypeQualifierDefault({ElementType.TYPE_USE, ElementType.METHOD})
|
||||
public @interface NonNullApi {
|
||||
}
|
||||
|
||||
// FILE: spr/NullableApi.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;
|
||||
import javax.annotation.meta.When;
|
||||
|
||||
@Target({ElementType.TYPE_USE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Nonnull(when = When.MAYBE)
|
||||
@TypeQualifierDefault({ElementType.TYPE_USE})
|
||||
public @interface NullableApi {
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import spr.*;
|
||||
import java.util.*;
|
||||
|
||||
@NonNullApi
|
||||
public class A {
|
||||
public String foo(String x) { return ""; }
|
||||
public @NullableApi String bar(@NullableApi String y) { return ""; }
|
||||
public @NullableApi List<String> baz1() { return null; }
|
||||
public List<@NullableApi String> baz2() { return null; }
|
||||
public @NullableApi List<@NonNullApi String> baz3() { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a: A) {
|
||||
a.foo("").length
|
||||
a.foo(null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
a.bar("").length
|
||||
a.bar(null)<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
a.baz1().get(0).length
|
||||
a.baz1()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.get(0).length
|
||||
a.baz1()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.get(0)?.length
|
||||
|
||||
a.baz2().get(0).length
|
||||
a.baz2()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.get(0).length
|
||||
a.baz2()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.get(0)?.length
|
||||
|
||||
a.baz3().get(0).length
|
||||
a.baz3()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.get(0).length
|
||||
a.baz3()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.get(0)?.length
|
||||
}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
// SOURCE_RETENTION_ANNOTATIONS
|
||||
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
// FULL_JDK
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// ISSUE: KT-56656
|
||||
|
||||
// FILE: ParametricNullness.java
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
@Target({FIELD, METHOD, PARAMETER})
|
||||
@javax.annotation.meta.TypeQualifierNickname
|
||||
@javax.annotation.Nonnull(when = javax.annotation.meta.When.UNKNOWN)
|
||||
@interface ParametricNullness {}
|
||||
|
||||
// FILE: ElementTypesAreNonnullByDefault.java
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
/**
|
||||
* Marks all "top-level" types as non-null in a way that is recognized by Kotlin. Note that this
|
||||
* unfortunately includes type-variable usages, so we also provide {@link ParametricNullness} to
|
||||
* "undo" it as best we can.
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
@Target(TYPE)
|
||||
@TypeQualifierDefault({FIELD, METHOD, PARAMETER})
|
||||
@Nonnull
|
||||
@interface ElementTypesAreNonnullByDefault {}
|
||||
|
||||
// FILE: MyFunction.java
|
||||
import javax.annotation.CheckForNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@ElementTypesAreNonnullByDefault
|
||||
public interface MyFunction<F extends @Nullable Object, T extends @Nullable Object> extends java.util.function.Function<F, T> {
|
||||
@Override
|
||||
@ParametricNullness
|
||||
T apply (@ParametricNullness F input);
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class A<!> : MyFunction<String?, String?> {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun apply(x: String?): String? = ""
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FULL_JDK
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// ISSUE: KT-56656
|
||||
|
||||
Reference in New Issue
Block a user