Report warnings on overrides with wrong types nullability
^KT-48899 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
ec97dab6cd
commit
f7ef551f99
+12
@@ -17848,6 +17848,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullableWarnings.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesDefinitelyNonNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesWarning.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesWarning() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesWarning.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnCollection.kt")
|
||||
public void testReturnCollection() throws Exception {
|
||||
|
||||
+12
@@ -17848,6 +17848,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullableWarnings.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesDefinitelyNonNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesWarning.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesWarning() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesWarning.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnCollection.kt")
|
||||
public void testReturnCollection() throws Exception {
|
||||
|
||||
+12
@@ -17848,6 +17848,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullableWarnings.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesDefinitelyNonNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesWarning.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesWarning() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesWarning.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnCollection.kt")
|
||||
public void testReturnCollection() throws Exception {
|
||||
|
||||
+6
@@ -778,6 +778,12 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated extends A
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OverrideOfAnnotated.kt")
|
||||
public void testOverrideOfAnnotated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/OverrideOfAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SelfType.kt")
|
||||
public void testSelfType() throws Exception {
|
||||
|
||||
+6
@@ -778,6 +778,12 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTest
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OverrideOfAnnotated.kt")
|
||||
public void testOverrideOfAnnotated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/OverrideOfAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SelfType.kt")
|
||||
public void testSelfType() throws Exception {
|
||||
|
||||
+6
@@ -778,6 +778,12 @@ public class FirOldFrontendForeignAnnotationsSourceJavaTestGenerated extends Abs
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OverrideOfAnnotated.kt")
|
||||
public void testOverrideOfAnnotated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/OverrideOfAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SelfType.kt")
|
||||
public void testSelfType() throws Exception {
|
||||
|
||||
+15
-11
@@ -189,17 +189,6 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
|
||||
return metWrongNullabilityInsideArguments
|
||||
}
|
||||
|
||||
private fun isNullableTypeAgainstNotNullTypeParameter(
|
||||
subType: KotlinType,
|
||||
superType: KotlinType
|
||||
): Boolean {
|
||||
if (superType !is NotNullTypeVariable) return false
|
||||
return !AbstractNullabilityChecker.isSubtypeOfAny(
|
||||
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = true),
|
||||
subType
|
||||
)
|
||||
}
|
||||
|
||||
override fun checkReceiver(
|
||||
receiverParameter: ReceiverParameterDescriptor,
|
||||
receiverArgument: ReceiverValue,
|
||||
@@ -279,6 +268,10 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
|
||||
}
|
||||
|
||||
companion object {
|
||||
val typePreparatorUnwrappingEnhancement: KotlinTypePreparator = object : KotlinTypePreparator() {
|
||||
override fun prepareType(type: KotlinTypeMarker): UnwrappedType =
|
||||
super.prepareType(type).let { it.getEnhancementDeeply() ?: it }.unwrap()
|
||||
}
|
||||
val typeCheckerForEnhancedTypes = NewKotlinTypeCheckerImpl(
|
||||
kotlinTypeRefiner = KotlinTypeRefiner.Default,
|
||||
kotlinTypePreparator = object : KotlinTypePreparator() {
|
||||
@@ -287,6 +280,17 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
|
||||
}
|
||||
)
|
||||
val typeCheckerForBaseTypes = NewKotlinTypeCheckerImpl(KotlinTypeRefiner.Default)
|
||||
|
||||
fun isNullableTypeAgainstNotNullTypeParameter(
|
||||
subType: KotlinType,
|
||||
superType: KotlinType
|
||||
): Boolean {
|
||||
if (superType !is NotNullTypeVariable || subType is NotNullTypeVariable) return false
|
||||
return !AbstractNullabilityChecker.isSubtypeOfAny(
|
||||
createClassicTypeCheckerState(isErrorTypeEqualsToAnything = true),
|
||||
subType
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
object JavaOverrideWithWrongNullabilityOverrideChecker : DeclarationChecker {
|
||||
private val overridingUtilWithEnhancementUnwrapped =
|
||||
OverridingUtil
|
||||
.createWithTypePreparatorAndCustomSubtype(JavaNullabilityChecker.typePreparatorUnwrappingEnhancement) { subtype, supertype ->
|
||||
!JavaNullabilityChecker.isNullableTypeAgainstNotNullTypeParameter(subtype, supertype)
|
||||
}
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (descriptor !is CallableMemberDescriptor) return
|
||||
if (descriptor.overriddenDescriptors.isEmpty()) return
|
||||
|
||||
val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return
|
||||
|
||||
for (overriddenDescriptor in descriptor.overriddenDescriptors) {
|
||||
if (overriddenDescriptor !is JavaMethodDescriptor) continue
|
||||
// Skip, if even with enhancement unwrapped, it's still a valid override
|
||||
if (overridingUtilWithEnhancementUnwrapped
|
||||
.isOverridableBy(
|
||||
overriddenDescriptor, descriptor, containingClass, true
|
||||
).result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) continue
|
||||
|
||||
// Skip if it wasn't an override already before enhancement unwrappement, since errors already have been reported
|
||||
if (OverridingUtil.DEFAULT
|
||||
.isOverridableBy(
|
||||
overriddenDescriptor, descriptor, containingClass, true
|
||||
).result != OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) continue
|
||||
|
||||
|
||||
val unwrappedOverridden = overriddenDescriptor.substitute(TypeSubstitutor.create(object : TypeSubstitution() {
|
||||
override fun get(key: KotlinType): TypeProjection? = null
|
||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
||||
topLevelType.getEnhancementDeeply() ?: topLevelType
|
||||
})) ?: overriddenDescriptor
|
||||
|
||||
context.trace.report(ErrorsJvm.WRONG_NULLABILITY_FOR_JAVA_OVERRIDE.on(declaration, descriptor, unwrappedOverridden))
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+4
@@ -109,6 +109,10 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS,
|
||||
"Unsafe use of a nullable receiver of type {0}", RENDER_TYPE);
|
||||
|
||||
MAP.put(WRONG_NULLABILITY_FOR_JAVA_OVERRIDE,
|
||||
"Override ''{0}'' has incorrect nullability in its signature comparing with overridden ''{1}''", COMPACT, COMPACT);
|
||||
|
||||
|
||||
MAP.put(ANNOTATION_TARGETS_NON_EXISTENT_ACCESSOR,
|
||||
"An accessor will not be generated for ''{0}'', so the annotation will not be written to the class file", STRING);
|
||||
|
||||
|
||||
+3
-4
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.resolve.jvm.diagnostics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.Named;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -163,6 +160,8 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory1<KtElement, KotlinType> RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
||||
= DiagnosticFactory1.create(WARNING);
|
||||
|
||||
DiagnosticFactory2<KtModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor> WRONG_NULLABILITY_FOR_JAVA_OVERRIDE =
|
||||
DiagnosticFactory2.create(WARNING, OVERRIDE_MODIFIER);
|
||||
DiagnosticFactory1<KtAnnotationEntry, String> ANNOTATION_TARGETS_NON_EXISTENT_ACCESSOR = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
DiagnosticFactory1<PsiElement, String> SUSPENSION_POINT_INSIDE_MONITOR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+2
-1
@@ -41,7 +41,8 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
|
||||
JvmMultifileClassStateChecker,
|
||||
DefaultCheckerInTailrec,
|
||||
FunctionDelegateMemberNameClashChecker,
|
||||
ClassInheritsJavaSealedClassChecker
|
||||
ClassInheritsJavaSealedClassChecker,
|
||||
JavaOverrideWithWrongNullabilityOverrideChecker,
|
||||
),
|
||||
|
||||
additionalCallCheckers = listOf(
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// JSPECIFY_STATE: warn
|
||||
|
||||
// FILE: Foo.java
|
||||
public interface Foo {}
|
||||
// FILE: BaseClass.java
|
||||
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
@NullMarked
|
||||
public class BaseClass {
|
||||
public Foo everythingNotNullable(Foo x) { return null; }
|
||||
|
||||
public @Nullable Foo everythingNullable(@Nullable Foo x) { return null; }
|
||||
|
||||
public @NullnessUnspecified Foo everythingUnknown(@NullnessUnspecified Foo x) { return null; }
|
||||
|
||||
public @Nullable Foo mixed(Foo x) { return null; }
|
||||
|
||||
public Foo explicitlyNullnessUnspecified(@NullnessUnspecified Foo x) { return null; }
|
||||
}
|
||||
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
private val FOO = object : Foo {}
|
||||
|
||||
class Correct : BaseClass() {
|
||||
override fun everythingNotNullable(x: Foo): Foo {
|
||||
return FOO
|
||||
}
|
||||
|
||||
override fun everythingNullable(x: Foo?): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun everythingUnknown(x: Foo?): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun mixed(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun explicitlyNullnessUnspecified(x: Foo): Foo {
|
||||
return FOO
|
||||
}
|
||||
}
|
||||
|
||||
class WrongReturnTypes : BaseClass() {
|
||||
override fun everythingNotNullable(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun explicitlyNullnessUnspecified(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class WrongParameter : BaseClass() {
|
||||
override fun everythingNotNullable(x: Foo?): Foo {
|
||||
return FOO
|
||||
}
|
||||
|
||||
override fun everythingNullable(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun everythingUnknown(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun mixed(x: Foo?): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun explicitlyNullnessUnspecified(x: Foo?): Foo {
|
||||
return FOO
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// JSPECIFY_STATE: warn
|
||||
|
||||
// FILE: Foo.java
|
||||
public interface Foo {}
|
||||
// FILE: BaseClass.java
|
||||
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
@NullMarked
|
||||
public class BaseClass {
|
||||
public Foo everythingNotNullable(Foo x) { return null; }
|
||||
|
||||
public @Nullable Foo everythingNullable(@Nullable Foo x) { return null; }
|
||||
|
||||
public @NullnessUnspecified Foo everythingUnknown(@NullnessUnspecified Foo x) { return null; }
|
||||
|
||||
public @Nullable Foo mixed(Foo x) { return null; }
|
||||
|
||||
public Foo explicitlyNullnessUnspecified(@NullnessUnspecified Foo x) { return null; }
|
||||
}
|
||||
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
private val FOO = object : Foo {}
|
||||
|
||||
class Correct : BaseClass() {
|
||||
override fun everythingNotNullable(x: Foo): Foo {
|
||||
return FOO
|
||||
}
|
||||
|
||||
override fun everythingNullable(x: Foo?): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun everythingUnknown(x: Foo?): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun mixed(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun explicitlyNullnessUnspecified(x: Foo): Foo {
|
||||
return FOO
|
||||
}
|
||||
}
|
||||
|
||||
class WrongReturnTypes : BaseClass() {
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun everythingNotNullable(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun explicitlyNullnessUnspecified(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class WrongParameter : BaseClass() {
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun everythingNotNullable(x: Foo?): Foo {
|
||||
return FOO
|
||||
}
|
||||
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun everythingNullable(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun everythingUnknown(x: Foo): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun mixed(x: Foo?): Foo? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun explicitlyNullnessUnspecified(x: Foo?): Foo {
|
||||
return FOO
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package
|
||||
|
||||
private val FOO: FOO.<no name provided>
|
||||
|
||||
@org.jspecify.nullness.NullMarked public open class BaseClass {
|
||||
public constructor BaseClass()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun everythingNotNullable(/*0*/ x: Foo!): Foo!
|
||||
@org.jspecify.nullness.Nullable public open fun everythingNullable(/*0*/ @org.jspecify.nullness.Nullable x: @org.jspecify.nullness.Nullable Foo!): @org.jspecify.nullness.Nullable Foo!
|
||||
@org.jspecify.nullness.NullnessUnspecified public open fun everythingUnknown(/*0*/ @org.jspecify.nullness.NullnessUnspecified x: @org.jspecify.nullness.NullnessUnspecified Foo!): @org.jspecify.nullness.NullnessUnspecified Foo!
|
||||
public open fun explicitlyNullnessUnspecified(/*0*/ @org.jspecify.nullness.NullnessUnspecified x: @org.jspecify.nullness.NullnessUnspecified Foo!): Foo!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@org.jspecify.nullness.Nullable public open fun mixed(/*0*/ x: Foo!): @org.jspecify.nullness.Nullable Foo!
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Correct : BaseClass {
|
||||
public constructor Correct()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun everythingNotNullable(/*0*/ x: Foo): Foo
|
||||
public open override /*1*/ fun everythingNullable(/*0*/ x: Foo?): Foo?
|
||||
public open override /*1*/ fun everythingUnknown(/*0*/ x: Foo?): Foo?
|
||||
public open override /*1*/ fun explicitlyNullnessUnspecified(/*0*/ x: Foo): Foo
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ fun mixed(/*0*/ x: Foo): Foo?
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface Foo {
|
||||
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
|
||||
}
|
||||
|
||||
public final class WrongParameter : BaseClass {
|
||||
public constructor WrongParameter()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun everythingNotNullable(/*0*/ x: Foo?): Foo
|
||||
public open override /*1*/ fun everythingNullable(/*0*/ x: Foo): Foo?
|
||||
public open override /*1*/ fun everythingUnknown(/*0*/ x: Foo): Foo?
|
||||
public open override /*1*/ fun explicitlyNullnessUnspecified(/*0*/ x: Foo?): Foo
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ fun mixed(/*0*/ x: Foo?): Foo?
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class WrongReturnTypes : BaseClass {
|
||||
public constructor WrongReturnTypes()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun everythingNotNullable(/*0*/ x: Foo): Foo?
|
||||
@org.jspecify.nullness.Nullable public open override /*1*/ /*fake_override*/ fun everythingNullable(/*0*/ @org.jspecify.nullness.Nullable x: @org.jspecify.nullness.Nullable Foo!): @org.jspecify.nullness.Nullable Foo!
|
||||
@org.jspecify.nullness.NullnessUnspecified public open override /*1*/ /*fake_override*/ fun everythingUnknown(/*0*/ @org.jspecify.nullness.NullnessUnspecified x: @org.jspecify.nullness.NullnessUnspecified Foo!): @org.jspecify.nullness.NullnessUnspecified Foo!
|
||||
public open override /*1*/ fun explicitlyNullnessUnspecified(/*0*/ x: Foo): Foo?
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@org.jspecify.nullness.Nullable public open override /*1*/ /*fake_override*/ fun mixed(/*0*/ x: Foo!): @org.jspecify.nullness.Nullable Foo!
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// !SKIP_JAVAC
|
||||
// !LANGUAGE: -ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||
// !LANGUAGE: +DefinitelyNonNullableTypes
|
||||
// FILE: SLRUMap.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public interface SLRUMap<V> {
|
||||
void takeV(@NotNull V value);
|
||||
<E> void takeE(@NotNull E value);
|
||||
|
||||
void takeVList(@NotNull List<@NotNull V> value);
|
||||
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||
|
||||
public <K> K id(K value) { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
interface Q1<X> : SLRUMap<X> {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun takeV(x: X)
|
||||
override fun <E1> takeE(e: E1)
|
||||
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun takeVList(l: List<X>)
|
||||
override fun <E2> takeEList(l2: List<E2>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
|
||||
interface Q2<X> : SLRUMap<X> {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun takeV(x: X & Any)
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun <E1> takeE(e: E1 & Any)
|
||||
|
||||
override fun takeVList(l: List<X & Any>)
|
||||
override fun <E2> takeEList(l2: List<E2 & Any>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// !SKIP_JAVAC
|
||||
// !LANGUAGE: -ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||
// !LANGUAGE: +DefinitelyNonNullableTypes
|
||||
// FILE: SLRUMap.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public interface SLRUMap<V> {
|
||||
void takeV(@NotNull V value);
|
||||
<E> void takeE(@NotNull E value);
|
||||
|
||||
void takeVList(@NotNull List<@NotNull V> value);
|
||||
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||
|
||||
public <K> K id(K value) { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
interface Q1<X> : SLRUMap<X> {
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun takeV(x: X)
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun <E1> takeE(e: E1)
|
||||
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun takeVList(l: List<X>)
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun <E2> takeEList(l2: List<E2>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
|
||||
interface Q2<X> : SLRUMap<X> {
|
||||
override fun takeV(x: X & Any)
|
||||
override fun <E1> takeE(e: E1 & Any)
|
||||
|
||||
override fun takeVList(l: List<X & Any>)
|
||||
override fun <E2> takeEList(l2: List<E2 & Any>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package
|
||||
|
||||
public interface Q1</*0*/ X> : SLRUMap<X> {
|
||||
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 abstract override /*1*/ fun </*0*/ K2> id(/*0*/ k2: K2): K2
|
||||
public abstract override /*1*/ fun </*0*/ E1> takeE(/*0*/ e: E1): kotlin.Unit
|
||||
public abstract override /*1*/ fun </*0*/ E2> takeEList(/*0*/ l2: kotlin.collections.List<E2>): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeV(/*0*/ x: X): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeVList(/*0*/ l: kotlin.collections.List<X>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface Q2</*0*/ X> : SLRUMap<X> {
|
||||
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 abstract override /*1*/ fun </*0*/ K2> id(/*0*/ k2: K2): K2
|
||||
public abstract override /*1*/ fun </*0*/ E1> takeE(/*0*/ e: E1 & Any): kotlin.Unit
|
||||
public abstract override /*1*/ fun </*0*/ E2> takeEList(/*0*/ l2: kotlin.collections.List<E2 & Any>): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeV(/*0*/ x: X & Any): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeVList(/*0*/ l: kotlin.collections.List<X & Any>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface SLRUMap</*0*/ V : kotlin.Any!> {
|
||||
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 abstract fun </*0*/ K : kotlin.Any!> id(/*0*/ value: K!): K!
|
||||
public abstract fun </*0*/ E : kotlin.Any!> takeE(/*0*/ @org.jetbrains.annotations.NotNull value: E): kotlin.Unit
|
||||
public abstract fun </*0*/ E : kotlin.Any!> takeEList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull E>): kotlin.Unit
|
||||
public abstract fun takeV(/*0*/ @org.jetbrains.annotations.NotNull value: V): kotlin.Unit
|
||||
public abstract fun takeVList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull V>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
// !SKIP_JAVAC
|
||||
// !LANGUAGE: -ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||
// FILE: SLRUMap.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public interface SLRUMap<V> {
|
||||
void takeV(@NotNull V value);
|
||||
<E> void takeE(@NotNull E value);
|
||||
|
||||
void takeVList(@NotNull List<@NotNull V> value);
|
||||
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||
|
||||
public <K> K id(K value) { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
interface Q1<X> : SLRUMap<X> {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun takeV(x: X)
|
||||
override fun <E1> takeE(e: E1)
|
||||
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun takeVList(l: List<X>)
|
||||
override fun <E2> takeEList(l2: List<E2>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
|
||||
interface Q2<X : Any> : SLRUMap<X> {
|
||||
override fun takeV(x: X)
|
||||
override fun <E1 : Any> takeE(e: E1)
|
||||
|
||||
override fun takeVList(l: List<X>)
|
||||
override fun <E2 : Any> takeEList(l2: List<E2>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
// !SKIP_JAVAC
|
||||
// !LANGUAGE: -ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||
// FILE: SLRUMap.java
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
public interface SLRUMap<V> {
|
||||
void takeV(@NotNull V value);
|
||||
<E> void takeE(@NotNull E value);
|
||||
|
||||
void takeVList(@NotNull List<@NotNull V> value);
|
||||
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||
|
||||
public <K> K id(K value) { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
interface Q1<X> : SLRUMap<X> {
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun takeV(x: X)
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun <E1> takeE(e: E1)
|
||||
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun takeVList(l: List<X>)
|
||||
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun <E2> takeEList(l2: List<E2>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
|
||||
interface Q2<X : Any> : SLRUMap<X> {
|
||||
override fun takeV(x: X)
|
||||
override fun <E1 : Any> takeE(e: E1)
|
||||
|
||||
override fun takeVList(l: List<X>)
|
||||
override fun <E2 : Any> takeEList(l2: List<E2>)
|
||||
|
||||
override fun <K2> id(k2: K2): K2
|
||||
}
|
||||
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
package
|
||||
|
||||
public interface Q1</*0*/ X> : SLRUMap<X> {
|
||||
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 abstract override /*1*/ fun </*0*/ K2> id(/*0*/ k2: K2): K2
|
||||
public abstract override /*1*/ fun </*0*/ E1> takeE(/*0*/ e: E1): kotlin.Unit
|
||||
public abstract override /*1*/ fun </*0*/ E2> takeEList(/*0*/ l2: kotlin.collections.List<E2>): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeV(/*0*/ x: X): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeVList(/*0*/ l: kotlin.collections.List<X>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface Q2</*0*/ X : kotlin.Any> : SLRUMap<X> {
|
||||
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 abstract override /*1*/ fun </*0*/ K2> id(/*0*/ k2: K2): K2
|
||||
public abstract override /*1*/ fun </*0*/ E1 : kotlin.Any> takeE(/*0*/ e: E1): kotlin.Unit
|
||||
public abstract override /*1*/ fun </*0*/ E2 : kotlin.Any> takeEList(/*0*/ l2: kotlin.collections.List<E2>): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeV(/*0*/ x: X): kotlin.Unit
|
||||
public abstract override /*1*/ fun takeVList(/*0*/ l: kotlin.collections.List<X>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface SLRUMap</*0*/ V : kotlin.Any!> {
|
||||
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 abstract fun </*0*/ K : kotlin.Any!> id(/*0*/ value: K!): K!
|
||||
public abstract fun </*0*/ E : kotlin.Any!> takeE(/*0*/ @org.jetbrains.annotations.NotNull value: E): kotlin.Unit
|
||||
public abstract fun </*0*/ E : kotlin.Any!> takeEList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull E>): kotlin.Unit
|
||||
public abstract fun takeV(/*0*/ @org.jetbrains.annotations.NotNull value: V): kotlin.Unit
|
||||
public abstract fun takeVList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull V>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Generated
+12
@@ -17854,6 +17854,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullableWarnings.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesDefinitelyNonNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesDefinitelyNonNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("notNullTypeParameterWithKotlinOverridesWarning.kt")
|
||||
public void testNotNullTypeParameterWithKotlinOverridesWarning() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinOverridesWarning.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnCollection.kt")
|
||||
public void testReturnCollection() throws Exception {
|
||||
|
||||
+6
@@ -778,6 +778,12 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OverrideOfAnnotated.kt")
|
||||
public void testOverrideOfAnnotated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/OverrideOfAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SelfType.kt")
|
||||
public void testSelfType() throws Exception {
|
||||
|
||||
+6
@@ -778,6 +778,12 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OverrideOfAnnotated.kt")
|
||||
public void testOverrideOfAnnotated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/OverrideOfAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SelfType.kt")
|
||||
public void testSelfType() throws Exception {
|
||||
|
||||
+6
@@ -778,6 +778,12 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OverrideOfAnnotated.kt")
|
||||
public void testOverrideOfAnnotated() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/OverrideOfAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SelfType.kt")
|
||||
public void testSelfType() throws Exception {
|
||||
|
||||
@@ -445,9 +445,10 @@ object AbstractTypeChecker {
|
||||
return true
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTypeKind::class)
|
||||
private fun TypeSystemContext.isCommonDenotableType(type: KotlinTypeMarker): Boolean =
|
||||
type.typeConstructor().isDenotable() &&
|
||||
!type.isDynamic() && !type.isDefinitelyNotNullType() &&
|
||||
!type.isDynamic() && !type.isDefinitelyNotNullType() && !type.isNotNullTypeVariable() &&
|
||||
type.lowerBoundIfFlexible().typeConstructor() == type.upperBoundIfFlexible().typeConstructor()
|
||||
|
||||
fun effectiveVariance(declared: TypeVariance, useSite: TypeVariance): TypeVariance? {
|
||||
@@ -702,7 +703,8 @@ object AbstractNullabilityChecker {
|
||||
if (superType.isMarkedNullable()) return true
|
||||
|
||||
// i.e. subType is definitely not null
|
||||
if (subType.isDefinitelyNotNullType()) return true
|
||||
@OptIn(ObsoleteTypeKind::class)
|
||||
if (subType.isDefinitelyNotNullType() || subType.isNotNullTypeVariable()) return true
|
||||
|
||||
// i.e. subType is captured type, projection of which is marked not-null
|
||||
if (subType is CapturedTypeMarker && subType.isProjectionNotNull()) return true
|
||||
|
||||
@@ -377,6 +377,11 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
||||
|
||||
fun KotlinTypeMarker.isDefinitelyNotNullType(): Boolean = asSimpleType()?.asDefinitelyNotNullType() != null
|
||||
|
||||
// This kind of types is obsolete (expected to be removed at 1.7) and shouldn't be used further in a new code
|
||||
// Now, such types are being replaced with definitely non-nullable types
|
||||
@ObsoleteTypeKind
|
||||
fun KotlinTypeMarker.isNotNullTypeVariable(): Boolean = false
|
||||
|
||||
fun KotlinTypeMarker.hasFlexibleNullability() =
|
||||
lowerBoundIfFlexible().isMarkedNullable() != upperBoundIfFlexible().isMarkedNullable()
|
||||
|
||||
@@ -495,3 +500,6 @@ fun requireOrDescribe(condition: Boolean, value: Any?) {
|
||||
"Unexpected: value = '$value'$typeInfo"
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresOptIn("This kinds of type is obsolete and should not be used until you really need it")
|
||||
annotation class ObsoleteTypeKind
|
||||
|
||||
@@ -60,18 +60,23 @@ public class OverridingUtil {
|
||||
};
|
||||
|
||||
static {
|
||||
|
||||
DEFAULT = new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, KotlinTypeRefiner.Default.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverridingUtil createWithEqualityAxioms(@NotNull KotlinTypeChecker.TypeConstructorEquality equalityAxioms) {
|
||||
return new OverridingUtil(equalityAxioms, KotlinTypeRefiner.Default.INSTANCE);
|
||||
DEFAULT = new OverridingUtil(
|
||||
DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, KotlinTypeRefiner.Default.INSTANCE, KotlinTypePreparator.Default.INSTANCE,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverridingUtil createWithTypeRefiner(@NotNull KotlinTypeRefiner kotlinTypeRefiner) {
|
||||
return new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, kotlinTypeRefiner);
|
||||
return new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, kotlinTypeRefiner, KotlinTypePreparator.Default.INSTANCE, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverridingUtil createWithTypePreparatorAndCustomSubtype(
|
||||
@NotNull KotlinTypePreparator kotlinTypePreparator,
|
||||
@NotNull Function2<KotlinType, KotlinType, Boolean> customSubtype
|
||||
) {
|
||||
return new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, KotlinTypeRefiner.Default.INSTANCE, kotlinTypePreparator, customSubtype);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -79,18 +84,24 @@ public class OverridingUtil {
|
||||
@NotNull KotlinTypeRefiner kotlinTypeRefiner,
|
||||
@NotNull KotlinTypeChecker.TypeConstructorEquality equalityAxioms
|
||||
) {
|
||||
return new OverridingUtil(equalityAxioms, kotlinTypeRefiner);
|
||||
return new OverridingUtil(equalityAxioms, kotlinTypeRefiner, KotlinTypePreparator.Default.INSTANCE, null);
|
||||
}
|
||||
|
||||
private final KotlinTypeRefiner kotlinTypeRefiner;
|
||||
private final KotlinTypePreparator kotlinTypePreparator;
|
||||
private final KotlinTypeChecker.TypeConstructorEquality equalityAxioms;
|
||||
private final Function2<KotlinType, KotlinType, Boolean> customSubtype;
|
||||
|
||||
private OverridingUtil(
|
||||
@NotNull KotlinTypeChecker.TypeConstructorEquality axioms,
|
||||
@NotNull KotlinTypeRefiner kotlinTypeRefiner
|
||||
@NotNull KotlinTypeRefiner kotlinTypeRefiner,
|
||||
@NotNull KotlinTypePreparator kotlinTypePreparator,
|
||||
@Nullable Function2<KotlinType, KotlinType, Boolean> customSubtype
|
||||
) {
|
||||
equalityAxioms = axioms;
|
||||
this.kotlinTypeRefiner = kotlinTypeRefiner;
|
||||
this.kotlinTypePreparator = kotlinTypePreparator;
|
||||
this.customSubtype = customSubtype;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,8 +406,9 @@ public class OverridingUtil {
|
||||
"Should be the same number of type parameters: " + firstParameters + " vs " + secondParameters;
|
||||
|
||||
if (firstParameters.isEmpty()) {
|
||||
return new OverridingUtilTypeSystemContext(null, equalityAxioms, kotlinTypeRefiner)
|
||||
.newTypeCheckerState(true, true);
|
||||
return new OverridingUtilTypeSystemContext(
|
||||
null, equalityAxioms, kotlinTypeRefiner, kotlinTypePreparator, customSubtype
|
||||
).newTypeCheckerState(true, true);
|
||||
}
|
||||
|
||||
Map<TypeConstructor, TypeConstructor> matchingTypeConstructors = new HashMap<TypeConstructor, TypeConstructor>();
|
||||
@@ -404,8 +416,9 @@ public class OverridingUtil {
|
||||
matchingTypeConstructors.put(firstParameters.get(i).getTypeConstructor(), secondParameters.get(i).getTypeConstructor());
|
||||
}
|
||||
|
||||
return new OverridingUtilTypeSystemContext(matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner)
|
||||
.newTypeCheckerState(true, true);
|
||||
return new OverridingUtilTypeSystemContext(
|
||||
matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner, kotlinTypePreparator, customSubtype
|
||||
).newTypeCheckerState(true, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+26
-10
@@ -5,18 +5,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.types.checker.createClassicTypeCheckerState
|
||||
import org.jetbrains.kotlin.types.checker.*
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
|
||||
class OverridingUtilTypeSystemContext(
|
||||
val matchingTypeConstructors: Map<TypeConstructor, TypeConstructor>?,
|
||||
private val equalityAxioms: KotlinTypeChecker.TypeConstructorEquality,
|
||||
val kotlinTypeRefiner: KotlinTypeRefiner
|
||||
private val kotlinTypeRefiner: KotlinTypeRefiner,
|
||||
private val kotlinTypePreparator: KotlinTypePreparator,
|
||||
private val customSubtype: ((KotlinType, KotlinType) -> Boolean)? = null,
|
||||
) : ClassicTypeSystemContext {
|
||||
|
||||
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
|
||||
@@ -29,12 +30,27 @@ class OverridingUtilTypeSystemContext(
|
||||
errorTypesEqualToAnything: Boolean,
|
||||
stubTypesEqualToAnything: Boolean
|
||||
): TypeCheckerState {
|
||||
return createClassicTypeCheckerState(
|
||||
errorTypesEqualToAnything,
|
||||
stubTypesEqualToAnything,
|
||||
if (customSubtype == null) {
|
||||
return createClassicTypeCheckerState(
|
||||
errorTypesEqualToAnything,
|
||||
stubTypesEqualToAnything,
|
||||
typeSystemContext = this,
|
||||
kotlinTypeRefiner = kotlinTypeRefiner,
|
||||
kotlinTypePreparator = kotlinTypePreparator,
|
||||
)
|
||||
}
|
||||
|
||||
return object : TypeCheckerState(
|
||||
errorTypesEqualToAnything, stubTypesEqualToAnything, allowedTypeVariable = true,
|
||||
typeSystemContext = this,
|
||||
kotlinTypeRefiner = kotlinTypeRefiner
|
||||
)
|
||||
kotlinTypePreparator, kotlinTypeRefiner,
|
||||
) {
|
||||
override fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
|
||||
require(subType is KotlinType)
|
||||
require(superType is KotlinType)
|
||||
return customSubtype.invoke(subType, superType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun areEqualTypeConstructorsByAxioms(a: TypeConstructor, b: TypeConstructor): Boolean {
|
||||
|
||||
@@ -150,6 +150,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
return this as? DefinitelyNotNullType
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTypeKind::class)
|
||||
override fun KotlinTypeMarker.isNotNullTypeVariable(): Boolean = this is NotNullTypeVariable
|
||||
|
||||
override fun SimpleTypeMarker.isMarkedNullable(): Boolean {
|
||||
require(this is SimpleType, this::errorMessage)
|
||||
return this.isMarkedNullable
|
||||
|
||||
Reference in New Issue
Block a user