FE: prefer enhancements for errors over enhancements for warnings
This commit is contained in:
Vendored
+1
-1
@@ -34,7 +34,7 @@ public open class BK : B {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@org.jspecify.nullness.NullMarked public open class C</*0*/ E : C<E!>!> : SelfType<E> {
|
||||
@org.jspecify.nullness.NullMarked public open class C</*0*/ E : C<E!>!> : SelfType<E!> {
|
||||
public constructor C</*0*/ E : C<E!>!>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun foo(/*0*/ t: E!): kotlin.Unit
|
||||
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// JSR305_GLOBAL_REPORT: ignore
|
||||
// JSR305_MIGRATION_REPORT: ignore
|
||||
// JSR305_SPECIAL_REPORT: MyNonnull:warn, MyMigrationNonnull:strict
|
||||
|
||||
// FILE: A.java
|
||||
import javax.annotation.*;
|
||||
|
||||
public class A {
|
||||
@MyMigrationNullable public String field = null;
|
||||
|
||||
@MyMigrationNullable
|
||||
public String foo(@MyMigrationNonnull String x, CharSequence y) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@MyNonnull
|
||||
@MyMigrationNonnull
|
||||
public String bar() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a: A) {
|
||||
a.foo("", null)?.length
|
||||
a.foo("", null).length
|
||||
a.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, "").length
|
||||
|
||||
a.bar().length
|
||||
a.bar()!!.length
|
||||
|
||||
a.field?.length
|
||||
a.field.length
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
// JSR305_GLOBAL_REPORT: ignore
|
||||
// JSR305_MIGRATION_REPORT: ignore
|
||||
|
||||
+2
-1
@@ -5,9 +5,10 @@ public fun main(/*0*/ a: A): kotlin.Unit
|
||||
public open class A {
|
||||
public constructor A()
|
||||
@MyMigrationNullable public final var field: kotlin.String!
|
||||
@MyNonnull @MyMigrationNonnull public open fun bar(): kotlin.String!
|
||||
@MyNonnull @MyMigrationNonnull public open fun bar(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@MyMigrationNullable public open fun foo(/*0*/ @MyMigrationNonnull x: kotlin.String, /*1*/ 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
|
||||
}
|
||||
|
||||
|
||||
+13
-5
@@ -121,17 +121,25 @@ abstract class AbstractAnnotationTypeQualifierResolver<TAnnotation : Any>(
|
||||
fun extractNullability(
|
||||
annotations: Iterable<TAnnotation>, forceWarning: TAnnotation.() -> Boolean = { false }
|
||||
): NullabilityQualifierWithMigrationStatus? =
|
||||
annotations.firstNotNullOfOrNull { extractNullability(it, forceWarning) }
|
||||
annotations.fold(null as NullabilityQualifierWithMigrationStatus?) { found, annotation ->
|
||||
val extracted = extractNullability(annotation, forceWarning)
|
||||
when {
|
||||
found == null -> extracted
|
||||
extracted == null || extracted == found -> found
|
||||
extracted.isForWarningOnly && !found.isForWarningOnly -> found
|
||||
!extracted.isForWarningOnly && found.isForWarningOnly -> extracted
|
||||
else -> return null // inconsistent
|
||||
}
|
||||
}
|
||||
|
||||
fun extractMutability(annotations: Iterable<TAnnotation>): MutabilityQualifier? {
|
||||
return annotations.fold(null as MutabilityQualifier?) { found, annotation ->
|
||||
fun extractMutability(annotations: Iterable<TAnnotation>): MutabilityQualifier? =
|
||||
annotations.fold(null as MutabilityQualifier?) { found, annotation ->
|
||||
when (annotation.fqName) {
|
||||
in READ_ONLY_ANNOTATIONS -> MutabilityQualifier.READ_ONLY
|
||||
in MUTABLE_ANNOTATIONS -> MutabilityQualifier.MUTABLE
|
||||
else -> found
|
||||
else -> return@fold found
|
||||
}.also { if (found != null && found != it) return null /* inconsistent */ }
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractDefaultQualifiers(annotation: TAnnotation): JavaDefaultQualifiers? {
|
||||
resolveQualifierBuiltInDefaultAnnotation(annotation)?.let { return it }
|
||||
|
||||
+6
-11
@@ -135,18 +135,13 @@ abstract class AbstractSignatureParts<TAnnotation : Any> {
|
||||
a: NullabilityQualifierWithMigrationStatus?,
|
||||
b: NullabilityQualifierWithMigrationStatus?
|
||||
): NullabilityQualifierWithMigrationStatus? {
|
||||
if (a == null) return b
|
||||
if (a == null) return b // null < not null
|
||||
if (b == null) return a
|
||||
// TODO: this probably behaves really weirdly when some of those are warnings.
|
||||
if (a.qualifier == NullabilityQualifier.FORCE_FLEXIBILITY) return b
|
||||
if (b.qualifier == NullabilityQualifier.FORCE_FLEXIBILITY) return a
|
||||
if (a.qualifier == NullabilityQualifier.NULLABLE) return b
|
||||
if (b.qualifier == NullabilityQualifier.NULLABLE) return a
|
||||
assert(a.qualifier == b.qualifier && a.qualifier == NullabilityQualifier.NOT_NULL) {
|
||||
"Expected everything is NOT_NULL, but $a and $b are found"
|
||||
}
|
||||
|
||||
return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
|
||||
if (a.isForWarningOnly && !b.isForWarningOnly) return b // warnings < errors
|
||||
if (!a.isForWarningOnly && b.isForWarningOnly) return a
|
||||
if (a.qualifier < b.qualifier) return b // T! < T? < T
|
||||
if (a.qualifier > b.qualifier) return a
|
||||
return b // they are equal
|
||||
}
|
||||
|
||||
private val TypeParameterMarker.boundsNullability: NullabilityQualifierWithMigrationStatus?
|
||||
|
||||
+1
-1
@@ -6,9 +6,9 @@
|
||||
package org.jetbrains.kotlin.load.java.typeEnhancement
|
||||
|
||||
enum class NullabilityQualifier {
|
||||
FORCE_FLEXIBILITY,
|
||||
NULLABLE,
|
||||
NOT_NULL,
|
||||
FORCE_FLEXIBILITY
|
||||
}
|
||||
|
||||
enum class MutabilityQualifier {
|
||||
|
||||
Reference in New Issue
Block a user