[FIR] Implement warnings for java nullability upper bound violation
This commit is contained in:
committed by
Space Team
parent
2df1e9dde6
commit
a63ec9efdc
+16
@@ -5063,6 +5063,22 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS) { firDiagnostic ->
|
||||||
|
UpperBoundViolatedBasedOnJavaAnnotationsImpl(
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS) { firDiagnostic ->
|
||||||
|
UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotationsImpl(
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a),
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirJvmErrors.STRICTFP_ON_CLASS) { firDiagnostic ->
|
add(FirJvmErrors.STRICTFP_ON_CLASS) { firDiagnostic ->
|
||||||
StrictfpOnClassImpl(
|
StrictfpOnClassImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+12
@@ -3523,6 +3523,18 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = UpperBoundCannotBeArray::class
|
override val diagnosticClass get() = UpperBoundCannotBeArray::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface UpperBoundViolatedBasedOnJavaAnnotations : KtFirDiagnostic<PsiElement> {
|
||||||
|
override val diagnosticClass get() = UpperBoundViolatedBasedOnJavaAnnotations::class
|
||||||
|
val expectedUpperBound: KtType
|
||||||
|
val actualUpperBound: KtType
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations : KtFirDiagnostic<PsiElement> {
|
||||||
|
override val diagnosticClass get() = UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations::class
|
||||||
|
val expectedUpperBound: KtType
|
||||||
|
val actualUpperBound: KtType
|
||||||
|
}
|
||||||
|
|
||||||
interface StrictfpOnClass : KtFirDiagnostic<KtAnnotationEntry> {
|
interface StrictfpOnClass : KtFirDiagnostic<KtAnnotationEntry> {
|
||||||
override val diagnosticClass get() = StrictfpOnClass::class
|
override val diagnosticClass get() = StrictfpOnClass::class
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -4250,6 +4250,20 @@ internal class UpperBoundCannotBeArrayImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UpperBoundCannotBeArray
|
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UpperBoundCannotBeArray
|
||||||
|
|
||||||
|
internal class UpperBoundViolatedBasedOnJavaAnnotationsImpl(
|
||||||
|
override val expectedUpperBound: KtType,
|
||||||
|
override val actualUpperBound: KtType,
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UpperBoundViolatedBasedOnJavaAnnotations
|
||||||
|
|
||||||
|
internal class UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotationsImpl(
|
||||||
|
override val expectedUpperBound: KtType,
|
||||||
|
override val actualUpperBound: KtType,
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations
|
||||||
|
|
||||||
internal class StrictfpOnClassImpl(
|
internal class StrictfpOnClassImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
|
|||||||
+8
@@ -64,6 +64,14 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") {
|
|||||||
|
|
||||||
val TYPE_PARAMETERS by object : DiagnosticGroup("Type parameters") {
|
val TYPE_PARAMETERS by object : DiagnosticGroup("Type parameters") {
|
||||||
val UPPER_BOUND_CANNOT_BE_ARRAY by error<PsiElement>()
|
val UPPER_BOUND_CANNOT_BE_ARRAY by error<PsiElement>()
|
||||||
|
val UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS by warning<PsiElement> {
|
||||||
|
parameter<ConeKotlinType>("expectedUpperBound")
|
||||||
|
parameter<ConeKotlinType>("actualUpperBound")
|
||||||
|
}
|
||||||
|
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS by warning<PsiElement> {
|
||||||
|
parameter<ConeKotlinType>("expectedUpperBound")
|
||||||
|
parameter<ConeKotlinType>("actualUpperBound")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val ANNOTATIONS by object : DiagnosticGroup("annotations") {
|
val ANNOTATIONS by object : DiagnosticGroup("annotations") {
|
||||||
|
|||||||
+2
@@ -50,6 +50,8 @@ object FirJvmErrors {
|
|||||||
|
|
||||||
// Type parameters
|
// Type parameters
|
||||||
val UPPER_BOUND_CANNOT_BE_ARRAY by error0<PsiElement>()
|
val UPPER_BOUND_CANNOT_BE_ARRAY by error0<PsiElement>()
|
||||||
|
val UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS by warning2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||||
|
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS by warning2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||||
|
|
||||||
// annotations
|
// annotations
|
||||||
val STRICTFP_ON_CLASS by error0<KtAnnotationEntry>()
|
val STRICTFP_ON_CLASS by error0<KtAnnotationEntry>()
|
||||||
|
|||||||
+15
@@ -80,6 +80,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZ
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_INLINE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_INLINE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_SUSPEND
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_SUSPEND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.WRONG_NULLABILITY_FOR_JAVA_OVERRIDE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.WRONG_NULLABILITY_FOR_JAVA_OVERRIDE
|
||||||
|
|
||||||
@@ -108,6 +110,19 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
SYMBOL,
|
SYMBOL,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
map.put(
|
||||||
|
UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS,
|
||||||
|
"Type argument is not within its bounds: should be subtype of ''{0}''.",
|
||||||
|
RENDER_TYPE,
|
||||||
|
RENDER_TYPE
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS,
|
||||||
|
"Type argument is not within its bounds: should be subtype of ''{0}''.",
|
||||||
|
RENDER_TYPE,
|
||||||
|
RENDER_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
map.put(UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of type parameter cannot be an array.")
|
map.put(UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of type parameter cannot be an array.")
|
||||||
map.put(STRICTFP_ON_CLASS, "'@Strictfp' annotation on classes is not yet supported.")
|
map.put(STRICTFP_ON_CLASS, "'@Strictfp' annotation on classes is not yet supported.")
|
||||||
map.put(SYNCHRONIZED_ON_ABSTRACT, "'@Synchronized' annotation cannot be used on abstract functions.")
|
map.put(SYNCHRONIZED_ON_ABSTRACT, "'@Synchronized' annotation cannot be used on abstract functions.")
|
||||||
|
|||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.jvm.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformUpperBoundsProvider
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
|
||||||
|
import org.jetbrains.kotlin.fir.java.enhancement.EnhancedForWarningConeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.fir.java.enhancement.enhancedTypeForWarning
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.typeContext
|
||||||
|
|
||||||
|
class FirJavaNullabilityWarningUpperBoundsProvider(session: FirSession) : FirPlatformUpperBoundsProvider {
|
||||||
|
private val substitutor: EnhancedForWarningConeSubstitutor = EnhancedForWarningConeSubstitutor(session.typeContext)
|
||||||
|
|
||||||
|
override val diagnostic: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType>
|
||||||
|
get() = FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS
|
||||||
|
|
||||||
|
override val diagnosticForTypeAlias: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType>
|
||||||
|
get() = FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS
|
||||||
|
|
||||||
|
override fun getAdditionalUpperBound(coneKotlinType: ConeKotlinType): ConeKotlinType? {
|
||||||
|
return substitutor.substituteOrNull(coneKotlinType)
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -7,8 +7,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
@@ -179,6 +181,7 @@ fun checkUpperBoundViolated(
|
|||||||
) {
|
) {
|
||||||
val count = minOf(typeParameters.size, typeArguments.size)
|
val count = minOf(typeParameters.size, typeArguments.size)
|
||||||
val typeSystemContext = context.session.typeContext
|
val typeSystemContext = context.session.typeContext
|
||||||
|
val additionalUpperBoundsProvider = context.session.platformUpperBoundsProvider
|
||||||
|
|
||||||
for (index in 0 until count) {
|
for (index in 0 until count) {
|
||||||
val argument = typeArguments[index]
|
val argument = typeArguments[index]
|
||||||
@@ -204,6 +207,22 @@ fun checkUpperBoundViolated(
|
|||||||
else -> FirErrors.UPPER_BOUND_VIOLATED
|
else -> FirErrors.UPPER_BOUND_VIOLATED
|
||||||
}
|
}
|
||||||
reporter.reportOn(argumentSource, factory, upperBound, argumentType.type, context)
|
reporter.reportOn(argumentSource, factory, upperBound, argumentType.type, context)
|
||||||
|
} else {
|
||||||
|
// Only check if the original check was successful to prevent duplicate diagnostics
|
||||||
|
val additionalUpperBound = additionalUpperBoundsProvider?.getAdditionalUpperBound(upperBound)
|
||||||
|
if (additionalUpperBound != null && !AbstractTypeChecker.isSubtypeOf(
|
||||||
|
typeSystemContext,
|
||||||
|
argumentType,
|
||||||
|
additionalUpperBound,
|
||||||
|
stubTypesEqualToAnything = true
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
val factory = when {
|
||||||
|
isReportExpansionError && argumentTypeRef == null -> additionalUpperBoundsProvider.diagnosticForTypeAlias
|
||||||
|
else -> additionalUpperBoundsProvider.diagnostic
|
||||||
|
}
|
||||||
|
reporter.reportOn(argumentSource, factory, upperBound, argumentType.type, context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,3 +281,12 @@ fun ConeTypeProjection.withSource(source: FirTypeRefSource?): ConeTypeProjection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface FirPlatformUpperBoundsProvider : FirSessionComponent {
|
||||||
|
val diagnostic: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType>
|
||||||
|
val diagnosticForTypeAlias: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType>
|
||||||
|
|
||||||
|
fun getAdditionalUpperBound(coneKotlinType: ConeKotlinType): ConeKotlinType?
|
||||||
|
}
|
||||||
|
|
||||||
|
val FirSession.platformUpperBoundsProvider: FirPlatformUpperBoundsProvider? by FirSession.nullableSessionComponentAccessor()
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ import org.jetbrains.kotlin.fir.*
|
|||||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponent
|
import org.jetbrains.kotlin.fir.analysis.CheckersComponent
|
||||||
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
|
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.FirInlineCheckerPlatformSpecificComponent
|
import org.jetbrains.kotlin.fir.analysis.checkers.FirInlineCheckerPlatformSpecificComponent
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformUpperBoundsProvider
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.FirPrimaryConstructorSuperTypeCheckerPlatformComponent
|
import org.jetbrains.kotlin.fir.analysis.checkers.FirPrimaryConstructorSuperTypeCheckerPlatformComponent
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirNameConflictsTracker
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirNameConflictsTracker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirGenericArrayClassLiteralSupport
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirGenericArrayClassLiteralSupport
|
||||||
import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper
|
import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJavaNullabilityWarningUpperBoundsProvider
|
||||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmAnnotationsPlatformSpecificSupportComponent
|
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmAnnotationsPlatformSpecificSupportComponent
|
||||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmInlineCheckerComponent
|
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmInlineCheckerComponent
|
||||||
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent
|
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent
|
||||||
@@ -162,6 +164,7 @@ fun FirSession.registerJavaComponents(
|
|||||||
register(FirInlineCheckerPlatformSpecificComponent::class, FirJvmInlineCheckerComponent())
|
register(FirInlineCheckerPlatformSpecificComponent::class, FirJvmInlineCheckerComponent())
|
||||||
register(FirGenericArrayClassLiteralSupport::class, FirGenericArrayClassLiteralSupport.Enabled)
|
register(FirGenericArrayClassLiteralSupport::class, FirGenericArrayClassLiteralSupport.Enabled)
|
||||||
register(FirDelegatedMembersFilter::class, FirJvmDelegatedMembersFilter(this))
|
register(FirDelegatedMembersFilter::class, FirJvmDelegatedMembersFilter(this))
|
||||||
|
register(FirPlatformUpperBoundsProvider::class, FirJavaNullabilityWarningUpperBoundsProvider(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------- Resolve components --------------------------
|
// -------------------------- Resolve components --------------------------
|
||||||
|
|||||||
+2
-1
@@ -12,7 +12,8 @@ public class NullnessUnspecifiedTypeParameter<T> {
|
|||||||
public class Test {}
|
public class Test {}
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
// jspecify_nullness_mismatch
|
||||||
|
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||||
a1.foo(1)
|
a1.foo(1)
|
||||||
|
|||||||
+2
-1
@@ -13,7 +13,8 @@ public class NullnessUnspecifiedTypeParameter<T> {
|
|||||||
public class Test {}
|
public class Test {}
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
// jspecify_nullness_mismatch
|
||||||
|
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||||
a1.foo(1)
|
a1.foo(1)
|
||||||
|
|||||||
+10
-5
@@ -20,21 +20,26 @@ public class B<T> {
|
|||||||
public class Test {}
|
public class Test {}
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun <T : Test> main(a1: A<Any?>, a2: A<Test>, b1: B<Any?>, b2: B<Test>, x: T): Unit {
|
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||||
|
fun <T : Test> main(a1: A<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, a2: A<Test>, b1: B<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, b2: B<Test>, x: T): Unit {
|
||||||
a1.foo(null)
|
a1.foo(null)
|
||||||
a1.bar<T?>(null)
|
// jspecify_nullness_mismatch
|
||||||
|
a1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
a1.bar<T>(x)
|
a1.bar<T>(x)
|
||||||
|
|
||||||
a2.foo(null)
|
a2.foo(null)
|
||||||
a2.bar<T?>(null)
|
// jspecify_nullness_mismatch
|
||||||
|
a2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
a2.bar<T>(x)
|
a2.bar<T>(x)
|
||||||
|
|
||||||
b1.foo(null)
|
b1.foo(null)
|
||||||
b1.bar<T?>(null)
|
// jspecify_nullness_mismatch
|
||||||
|
b1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
b1.bar<T>(x)
|
b1.bar<T>(x)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
b2.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
b2.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||||
b2.bar<T?>(null)
|
// jspecify_nullness_mismatch
|
||||||
|
b2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
b2.bar<T>(x)
|
b2.bar<T>(x)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -13,7 +13,7 @@ public class Test {}
|
|||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||||
a1.foo(1)
|
a1.foo(1)
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ public class Test {}
|
|||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||||
a1.foo(1)
|
a1.foo(1)
|
||||||
|
|||||||
+5
-5
@@ -21,26 +21,26 @@ public class Test {}
|
|||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||||
fun <T : Test> main(a1: A<Any?>, a2: A<Test>, b1: B<Any?>, b2: B<Test>, x: T): Unit {
|
fun <T : Test> main(a1: A<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, a2: A<Test>, b1: B<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, b2: B<Test>, x: T): Unit {
|
||||||
a1.foo(null)
|
a1.foo(null)
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a1.bar<T?>(null)
|
a1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
a1.bar<T>(x)
|
a1.bar<T>(x)
|
||||||
|
|
||||||
a2.foo(null)
|
a2.foo(null)
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a2.bar<T?>(null)
|
a2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
a2.bar<T>(x)
|
a2.bar<T>(x)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
b1.foo(null)
|
b1.foo(null)
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
b1.bar<T?>(null)
|
b1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
b1.bar<T>(x)
|
b1.bar<T>(x)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
b2.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
b2.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
b2.bar<T?>(null)
|
b2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||||
b2.bar<T>(x)
|
b2.bar<T>(x)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
|
||||||
// SKIP_TXT
|
|
||||||
|
|
||||||
// FILE: J1.java
|
|
||||||
import io.reactivex.rxjava3.annotations.*;
|
|
||||||
|
|
||||||
public class J1<@NonNull T> {}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
fun main() {
|
|
||||||
J1<Any?>() // violated nullability, no warnings; but there is an error with -Xtype-enhancement-improvements-strict-mode
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||||
// SKIP_TXT
|
// SKIP_TXT
|
||||||
|
|
||||||
|
|||||||
+1
@@ -57,6 +57,7 @@ internal val diagnosticsToJspecifyMarks = mapOf(
|
|||||||
|
|
||||||
FirJvmErrors.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch",
|
FirJvmErrors.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch",
|
||||||
FirJvmErrors.RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch",
|
FirJvmErrors.RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch",
|
||||||
|
FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch",
|
||||||
),
|
),
|
||||||
ReportLevel.STRICT to mapOf(
|
ReportLevel.STRICT to mapOf(
|
||||||
Errors.TYPE_MISMATCH to "jspecify_nullness_mismatch",
|
Errors.TYPE_MISMATCH to "jspecify_nullness_mismatch",
|
||||||
|
|||||||
Reference in New Issue
Block a user