Support type arguments enhancement from type parameters bounds
Currently, only works for codeanalysis annotations because type parameters bounds are enhanced only for them
This commit is contained in:
committed by
Victor Petukhov
parent
e9e05c53e1
commit
392ef9aa2b
Vendored
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||||
|
// FILE: A.java
|
||||||
|
|
||||||
|
import jspecify.annotations.*;
|
||||||
|
|
||||||
|
public class A<T extends @NotNull Object, E extends @Nullable Object, F extends @UnknownNullness Object> {
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: B.java
|
||||||
|
|
||||||
|
import jspecify.annotations.*;
|
||||||
|
|
||||||
|
@DefaultNullable
|
||||||
|
public class B {
|
||||||
|
public void bar(A<String, String, String> a) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: C.java
|
||||||
|
|
||||||
|
import jspecify.annotations.*;
|
||||||
|
|
||||||
|
@DefaultNotNull
|
||||||
|
public class C {
|
||||||
|
public void bar(A<String, String, String> a) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: D.java
|
||||||
|
|
||||||
|
import jspecify.annotations.*;
|
||||||
|
|
||||||
|
@DefaultUnknownNullness
|
||||||
|
public class D {
|
||||||
|
public void bar(A<String, String, String> a) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun main(
|
||||||
|
aNotNullNotNullNotNull: A<String, String, String>,
|
||||||
|
aNotNullNotNullNull: A<String, String, String?>,
|
||||||
|
aNotNullNullNotNull: A<String, String?, String>,
|
||||||
|
aNotNullNullNull: A<String, String?, String?>,
|
||||||
|
b: B, c: C, d: D
|
||||||
|
) {
|
||||||
|
b.bar(<!TYPE_MISMATCH!>aNotNullNotNullNotNull<!>)
|
||||||
|
b.bar(<!TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
||||||
|
b.bar(<!TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
||||||
|
b.bar(aNotNullNullNull)
|
||||||
|
|
||||||
|
c.bar(aNotNullNotNullNotNull)
|
||||||
|
c.bar(<!TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
||||||
|
c.bar(<!TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
||||||
|
c.bar(<!TYPE_MISMATCH!>aNotNullNullNull<!>)
|
||||||
|
|
||||||
|
d.bar(<!TYPE_MISMATCH!>aNotNullNotNullNotNull<!>)
|
||||||
|
d.bar(<!TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
||||||
|
d.bar(aNotNullNullNotNull)
|
||||||
|
d.bar(aNotNullNullNull)
|
||||||
|
}
|
||||||
Vendored
+34
@@ -0,0 +1,34 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(/*0*/ aNotNullNotNullNotNull: A<kotlin.String, kotlin.String, kotlin.String>, /*1*/ aNotNullNotNullNull: A<kotlin.String, kotlin.String, kotlin.String?>, /*2*/ aNotNullNullNotNull: A<kotlin.String, kotlin.String?, kotlin.String>, /*3*/ aNotNullNullNull: A<kotlin.String, kotlin.String?, kotlin.String?>, /*4*/ b: B, /*5*/ c: C, /*6*/ d: D): kotlin.Unit
|
||||||
|
|
||||||
|
public open class A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any, /*1*/ E, /*2*/ F : @jspecify.annotations.UnknownNullness kotlin.Any!> {
|
||||||
|
public constructor A</*0*/ T : @jspecify.annotations.NotNull kotlin.Any, /*1*/ E, /*2*/ F : @jspecify.annotations.UnknownNullness 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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
@jspecify.annotations.DefaultNullable public open class B {
|
||||||
|
public constructor B()
|
||||||
|
public open fun bar(/*0*/ a: A<kotlin.String, kotlin.String?, kotlin.String?>?): kotlin.Unit
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
@jspecify.annotations.DefaultNotNull public open class C {
|
||||||
|
public constructor C()
|
||||||
|
public open fun bar(/*0*/ a: A<kotlin.String, kotlin.String, kotlin.String>): kotlin.Unit
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
@DefaultUnknownNullness /* annotation class not found */ public open class D {
|
||||||
|
public constructor D()
|
||||||
|
public open fun bar(/*0*/ a: A<kotlin.String, kotlin.String?, kotlin.String!>!): kotlin.Unit
|
||||||
|
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
|
||||||
|
}
|
||||||
+5
@@ -70,6 +70,11 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathTestGenerated extends
|
|||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||||
|
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeArgumentsFromParameterBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeParameterBounds.kt")
|
@TestMetadata("typeParameterBounds.kt")
|
||||||
public void testTypeParameterBounds() throws Exception {
|
public void testTypeParameterBounds() throws Exception {
|
||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
||||||
|
|||||||
+5
@@ -70,6 +70,11 @@ public class ForeignJava8AnnotationsNoAnnotationInClasspathWithPsiClassReadingTe
|
|||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||||
|
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeArgumentsFromParameterBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeParameterBounds.kt")
|
@TestMetadata("typeParameterBounds.kt")
|
||||||
public void testTypeParameterBounds() throws Exception {
|
public void testTypeParameterBounds() throws Exception {
|
||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
||||||
|
|||||||
Generated
+5
@@ -70,6 +70,11 @@ public class ForeignJava8AnnotationsTestGenerated extends AbstractForeignJava8An
|
|||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||||
|
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeArgumentsFromParameterBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeParameterBounds.kt")
|
@TestMetadata("typeParameterBounds.kt")
|
||||||
public void testTypeParameterBounds() throws Exception {
|
public void testTypeParameterBounds() throws Exception {
|
||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
||||||
|
|||||||
+5
@@ -70,6 +70,11 @@ public class JavacForeignJava8AnnotationsTestGenerated extends AbstractJavacFore
|
|||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeArgumentsFromParameterBounds.kt")
|
||||||
|
public void testTypeArgumentsFromParameterBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeArgumentsFromParameterBounds.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeParameterBounds.kt")
|
@TestMetadata("typeParameterBounds.kt")
|
||||||
public void testTypeParameterBounds() throws Exception {
|
public void testTypeParameterBounds() throws Exception {
|
||||||
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
runTest("compiler/testData/foreignAnnotationsJava8/tests/jspecify/typeParameterBounds.kt");
|
||||||
|
|||||||
+2
-1
@@ -27,7 +27,8 @@ val DEFAULT_JSPECIFY_APPLICABILITY = listOf(
|
|||||||
AnnotationQualifierApplicabilityType.FIELD,
|
AnnotationQualifierApplicabilityType.FIELD,
|
||||||
AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE,
|
AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE,
|
||||||
AnnotationQualifierApplicabilityType.VALUE_PARAMETER,
|
AnnotationQualifierApplicabilityType.VALUE_PARAMETER,
|
||||||
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS
|
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS,
|
||||||
|
AnnotationQualifierApplicabilityType.TYPE_USE
|
||||||
)
|
)
|
||||||
|
|
||||||
val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf(
|
val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf(
|
||||||
|
|||||||
+65
-25
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.load.java.*
|
|||||||
import org.jetbrains.kotlin.load.java.descriptors.*
|
import org.jetbrains.kotlin.load.java.descriptors.*
|
||||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||||
import org.jetbrains.kotlin.load.java.lazy.copyWithNewDefaultTypeQualifiers
|
import org.jetbrains.kotlin.load.java.lazy.copyWithNewDefaultTypeQualifiers
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
||||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||||
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
|
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
|
||||||
@@ -311,7 +312,8 @@ class SignatureEnhancement(
|
|||||||
|
|
||||||
private fun KotlinType.extractQualifiersFromAnnotations(
|
private fun KotlinType.extractQualifiersFromAnnotations(
|
||||||
isHeadTypeConstructor: Boolean,
|
isHeadTypeConstructor: Boolean,
|
||||||
defaultQualifiersForType: JavaDefaultQualifiers?
|
defaultQualifiersForType: JavaDefaultQualifiers?,
|
||||||
|
typeParameterForArgument: TypeParameterDescriptor?
|
||||||
): JavaTypeQualifiers {
|
): JavaTypeQualifiers {
|
||||||
val composedAnnotation =
|
val composedAnnotation =
|
||||||
if (isHeadTypeConstructor && typeContainer != null)
|
if (isHeadTypeConstructor && typeContainer != null)
|
||||||
@@ -338,13 +340,11 @@ class SignatureEnhancement(
|
|||||||
val annotationsNullability = composedAnnotation.extractNullability()
|
val annotationsNullability = composedAnnotation.extractNullability()
|
||||||
val nullabilityInfo =
|
val nullabilityInfo =
|
||||||
annotationsNullability
|
annotationsNullability
|
||||||
?: nullabilityFromBoundsForTypeBasedOnTypeParameter
|
?: computeNullabilityInfoInTheAbsenceOfExplicitAnnotation(
|
||||||
?: defaultTypeQualifier?.nullabilityQualifier?.let { nullabilityQualifierWithMigrationStatus ->
|
nullabilityFromBoundsForTypeBasedOnTypeParameter,
|
||||||
NullabilityQualifierWithMigrationStatus(
|
defaultTypeQualifier,
|
||||||
nullabilityQualifierWithMigrationStatus.qualifier,
|
typeParameterForArgument
|
||||||
nullabilityQualifierWithMigrationStatus.isForWarningOnly
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val isNotNullTypeParameter =
|
val isNotNullTypeParameter =
|
||||||
if (annotationsNullability != null)
|
if (annotationsNullability != null)
|
||||||
@@ -367,12 +367,45 @@ class SignatureEnhancement(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun computeNullabilityInfoInTheAbsenceOfExplicitAnnotation(
|
||||||
|
nullabilityFromBoundsForTypeBasedOnTypeParameter: NullabilityQualifierWithMigrationStatus?,
|
||||||
|
defaultTypeQualifier: JavaDefaultQualifiers?,
|
||||||
|
typeParameterForArgument: TypeParameterDescriptor?
|
||||||
|
): NullabilityQualifierWithMigrationStatus? {
|
||||||
|
|
||||||
|
val result =
|
||||||
|
nullabilityFromBoundsForTypeBasedOnTypeParameter
|
||||||
|
?: defaultTypeQualifier?.nullabilityQualifier?.let { nullabilityQualifierWithMigrationStatus ->
|
||||||
|
NullabilityQualifierWithMigrationStatus(
|
||||||
|
nullabilityQualifierWithMigrationStatus.qualifier,
|
||||||
|
nullabilityQualifierWithMigrationStatus.isForWarningOnly
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val boundsFromTypeParameterForArgument = typeParameterForArgument?.boundsNullability() ?: return result
|
||||||
|
if (result == null) return NullabilityQualifierWithMigrationStatus(boundsFromTypeParameterForArgument)
|
||||||
|
|
||||||
|
return NullabilityQualifierWithMigrationStatus(
|
||||||
|
mostSpecific(boundsFromTypeParameterForArgument, result.qualifier)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mostSpecific(a: NullabilityQualifier, b: NullabilityQualifier): NullabilityQualifier {
|
||||||
|
if (a == NullabilityQualifier.FORCE_FLEXIBILITY) return b
|
||||||
|
if (b == NullabilityQualifier.FORCE_FLEXIBILITY) return a
|
||||||
|
if (a == NullabilityQualifier.NULLABLE) return b
|
||||||
|
if (b == NullabilityQualifier.NULLABLE) return a
|
||||||
|
assert(a == b && a == NullabilityQualifier.NOT_NULL) {
|
||||||
|
"Expected everything is NOT_NULL, but $a and $b are found"
|
||||||
|
}
|
||||||
|
|
||||||
|
return NullabilityQualifier.NOT_NULL
|
||||||
|
}
|
||||||
|
|
||||||
private fun KotlinType.nullabilityInfoBoundsForTypeParameterUsage(): Pair<NullabilityQualifierWithMigrationStatus?, Boolean> {
|
private fun KotlinType.nullabilityInfoBoundsForTypeParameterUsage(): Pair<NullabilityQualifierWithMigrationStatus?, Boolean> {
|
||||||
val typeParameterBoundsNullability =
|
val typeParameterBoundsNullability =
|
||||||
(constructor.declarationDescriptor as? TypeParameterDescriptor)?.boundsNullability() ?: return Pair(null, false)
|
(constructor.declarationDescriptor as? TypeParameterDescriptor)?.boundsNullability() ?: return Pair(null, false)
|
||||||
|
|
||||||
if (typeParameterBoundsNullability == NullabilityQualifier.FORCE_FLEXIBILITY) return Pair(null, false)
|
|
||||||
|
|
||||||
// If type parameter has a nullable (non-flexible) upper bound
|
// If type parameter has a nullable (non-flexible) upper bound
|
||||||
// We shouldn't mark its type usages as nullable:
|
// We shouldn't mark its type usages as nullable:
|
||||||
// interface A<T extends @Nullable Object> {
|
// interface A<T extends @Nullable Object> {
|
||||||
@@ -384,10 +417,14 @@ class SignatureEnhancement(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TypeParameterDescriptor.boundsNullability(): NullabilityQualifier = when {
|
private fun TypeParameterDescriptor.boundsNullability(): NullabilityQualifier? {
|
||||||
upperBounds.all(KotlinType::isNullabilityFlexible) -> NullabilityQualifier.FORCE_FLEXIBILITY
|
// Do not use bounds from Kotlin-defined type parameters
|
||||||
upperBounds.any { !it.isNullable() } -> NullabilityQualifier.NOT_NULL
|
if (this !is LazyJavaTypeParameterDescriptor) return null
|
||||||
else -> NullabilityQualifier.NULLABLE
|
return when {
|
||||||
|
upperBounds.all(KotlinType::isNullabilityFlexible) -> null
|
||||||
|
upperBounds.any { !it.isNullable() } -> NullabilityQualifier.NOT_NULL
|
||||||
|
else -> NullabilityQualifier.NULLABLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Annotations.extractNullability(): NullabilityQualifierWithMigrationStatus? =
|
private fun Annotations.extractNullability(): NullabilityQualifierWithMigrationStatus? =
|
||||||
@@ -410,11 +447,11 @@ class SignatureEnhancement(
|
|||||||
val isHeadTypeConstructor = index == 0
|
val isHeadTypeConstructor = index == 0
|
||||||
assert(isHeadTypeConstructor || !onlyHeadTypeConstructor) { "Only head type constructors should be computed" }
|
assert(isHeadTypeConstructor || !onlyHeadTypeConstructor) { "Only head type constructors should be computed" }
|
||||||
|
|
||||||
val (qualifiers, defaultQualifiers) = indexedThisType[index]
|
val (qualifiers, defaultQualifiers, typeParameterForArgument) = indexedThisType[index]
|
||||||
val verticalSlice = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type }
|
val verticalSlice = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type }
|
||||||
|
|
||||||
// Only the head type constructor is safely co-variant
|
// Only the head type constructor is safely co-variant
|
||||||
qualifiers.computeQualifiersForOverride(verticalSlice, defaultQualifiers, isHeadTypeConstructor)
|
qualifiers.computeQualifiersForOverride(verticalSlice, defaultQualifiers, isHeadTypeConstructor, typeParameterForArgument)
|
||||||
}
|
}
|
||||||
|
|
||||||
return { index -> computedResult.getOrElse(index) { JavaTypeQualifiers.NONE } }
|
return { index -> computedResult.getOrElse(index) { JavaTypeQualifiers.NONE } }
|
||||||
@@ -424,7 +461,7 @@ class SignatureEnhancement(
|
|||||||
private fun KotlinType.toIndexed(): List<TypeAndDefaultQualifiers> {
|
private fun KotlinType.toIndexed(): List<TypeAndDefaultQualifiers> {
|
||||||
val list = ArrayList<TypeAndDefaultQualifiers>(1)
|
val list = ArrayList<TypeAndDefaultQualifiers>(1)
|
||||||
|
|
||||||
fun add(type: KotlinType, ownerContext: LazyJavaResolverContext) {
|
fun add(type: KotlinType, ownerContext: LazyJavaResolverContext, typeParameterForArgument: TypeParameterDescriptor?) {
|
||||||
val c = ownerContext.copyWithNewDefaultTypeQualifiers(type.annotations)
|
val c = ownerContext.copyWithNewDefaultTypeQualifiers(type.annotations)
|
||||||
|
|
||||||
list.add(
|
list.add(
|
||||||
@@ -436,28 +473,30 @@ class SignatureEnhancement(
|
|||||||
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS
|
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS
|
||||||
else
|
else
|
||||||
AnnotationQualifierApplicabilityType.TYPE_USE
|
AnnotationQualifierApplicabilityType.TYPE_USE
|
||||||
)
|
),
|
||||||
|
typeParameterForArgument
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for (arg in type.arguments) {
|
for ((arg, parameter) in type.arguments.zip(type.constructor.parameters)) {
|
||||||
if (arg.isStarProjection) {
|
if (arg.isStarProjection) {
|
||||||
// TODO: sort out how to handle wildcards
|
// TODO: sort out how to handle wildcards
|
||||||
list.add(TypeAndDefaultQualifiers(arg.type, null))
|
list.add(TypeAndDefaultQualifiers(arg.type, null, parameter))
|
||||||
} else {
|
} else {
|
||||||
add(arg.type, c)
|
add(arg.type, c, parameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add(this, containerContext)
|
add(this, containerContext, typeParameterForArgument = null)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType.computeQualifiersForOverride(
|
private fun KotlinType.computeQualifiersForOverride(
|
||||||
fromSupertypes: Collection<KotlinType>,
|
fromSupertypes: Collection<KotlinType>,
|
||||||
defaultQualifiersForType: JavaDefaultQualifiers?,
|
defaultQualifiersForType: JavaDefaultQualifiers?,
|
||||||
isHeadTypeConstructor: Boolean
|
isHeadTypeConstructor: Boolean,
|
||||||
|
typeParameterForArgument: TypeParameterDescriptor?
|
||||||
): JavaTypeQualifiers {
|
): JavaTypeQualifiers {
|
||||||
val superQualifiers = fromSupertypes.map { it.extractQualifiers() }
|
val superQualifiers = fromSupertypes.map { it.extractQualifiers() }
|
||||||
val mutabilityFromSupertypes = superQualifiers.mapNotNull { it.mutability }.toSet()
|
val mutabilityFromSupertypes = superQualifiers.mapNotNull { it.mutability }.toSet()
|
||||||
@@ -466,7 +505,7 @@ class SignatureEnhancement(
|
|||||||
.mapNotNull { it.unwrapEnhancement().extractQualifiers().nullability }
|
.mapNotNull { it.unwrapEnhancement().extractQualifiers().nullability }
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
val own = extractQualifiersFromAnnotations(isHeadTypeConstructor, defaultQualifiersForType)
|
val own = extractQualifiersFromAnnotations(isHeadTypeConstructor, defaultQualifiersForType, typeParameterForArgument)
|
||||||
val ownNullability = own.takeIf { !it.isNullabilityQualifierForWarning }?.nullability
|
val ownNullability = own.takeIf { !it.isNullabilityQualifierForWarning }?.nullability
|
||||||
val ownNullabilityForWarning = own.nullability
|
val ownNullabilityForWarning = own.nullability
|
||||||
|
|
||||||
@@ -549,7 +588,8 @@ class SignatureEnhancement(
|
|||||||
|
|
||||||
private data class TypeAndDefaultQualifiers(
|
private data class TypeAndDefaultQualifiers(
|
||||||
val type: KotlinType,
|
val type: KotlinType,
|
||||||
val defaultQualifiers: JavaDefaultQualifiers?
|
val defaultQualifiers: JavaDefaultQualifiers?,
|
||||||
|
val typeParameterForArgument: TypeParameterDescriptor?
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun KotlinType.isNullabilityFlexible(): Boolean {
|
private fun KotlinType.isNullabilityFlexible(): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user