FIR: attach annotations to Java-converted cone types
This commit is contained in:
@@ -62,33 +62,6 @@ import java.lang.annotation.Documented
|
|||||||
import java.lang.annotation.Retention
|
import java.lang.annotation.Retention
|
||||||
import java.lang.annotation.Target
|
import java.lang.annotation.Target
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.Any
|
|
||||||
import kotlin.Array
|
|
||||||
import kotlin.Boolean
|
|
||||||
import kotlin.BooleanArray
|
|
||||||
import kotlin.Byte
|
|
||||||
import kotlin.ByteArray
|
|
||||||
import kotlin.Char
|
|
||||||
import kotlin.CharArray
|
|
||||||
import kotlin.Double
|
|
||||||
import kotlin.DoubleArray
|
|
||||||
import kotlin.Float
|
|
||||||
import kotlin.FloatArray
|
|
||||||
import kotlin.Int
|
|
||||||
import kotlin.IntArray
|
|
||||||
import kotlin.Long
|
|
||||||
import kotlin.LongArray
|
|
||||||
import kotlin.Short
|
|
||||||
import kotlin.ShortArray
|
|
||||||
import kotlin.String
|
|
||||||
import kotlin.Suppress
|
|
||||||
import kotlin.also
|
|
||||||
import kotlin.arrayOf
|
|
||||||
import kotlin.emptyArray
|
|
||||||
import kotlin.error
|
|
||||||
import kotlin.let
|
|
||||||
import kotlin.run
|
|
||||||
import kotlin.to
|
|
||||||
|
|
||||||
internal val JavaModifierListOwner.modality: Modality
|
internal val JavaModifierListOwner.modality: Modality
|
||||||
get() = when {
|
get() = when {
|
||||||
@@ -157,7 +130,7 @@ internal fun JavaClassifierType.toFirResolvedTypeRef(
|
|||||||
): FirResolvedTypeRef {
|
): FirResolvedTypeRef {
|
||||||
val coneType =
|
val coneType =
|
||||||
if (isForSupertypes)
|
if (isForSupertypes)
|
||||||
toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds, isForSupertypes)
|
toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, forTypeParameterBounds, isForSupertypes)
|
||||||
else
|
else
|
||||||
toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forTypeParameterBounds, isForSupertypes)
|
toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forTypeParameterBounds, isForSupertypes)
|
||||||
|
|
||||||
@@ -171,9 +144,15 @@ internal fun JavaType?.toConeKotlinTypeWithoutEnhancement(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
javaTypeParameterStack: JavaTypeParameterStack,
|
javaTypeParameterStack: JavaTypeParameterStack,
|
||||||
forAnnotationMember: Boolean = false,
|
forAnnotationMember: Boolean = false,
|
||||||
isForSupertypes: Boolean = false,
|
isForSupertypes: Boolean = false
|
||||||
attributes: ConeAttributes = ConeAttributes.Empty
|
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
|
val attributes = if (this != null && annotations.isNotEmpty()) {
|
||||||
|
ConeAttributes.create(
|
||||||
|
listOf(CustomAnnotationTypeAttribute(annotations.map { it.toFirAnnotationCall(session, javaTypeParameterStack) }))
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ConeAttributes.Empty
|
||||||
|
}
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is JavaClassifierType -> {
|
is JavaClassifierType -> {
|
||||||
toConeKotlinTypeWithoutEnhancement(
|
toConeKotlinTypeWithoutEnhancement(
|
||||||
@@ -206,14 +185,10 @@ internal fun JavaType?.toConeKotlinTypeWithoutEnhancement(
|
|||||||
bound?.toConeKotlinTypeWithoutEnhancement(
|
bound?.toConeKotlinTypeWithoutEnhancement(
|
||||||
session,
|
session,
|
||||||
javaTypeParameterStack,
|
javaTypeParameterStack,
|
||||||
isForSupertypes = isForSupertypes,
|
isForSupertypes = isForSupertypes
|
||||||
attributes = attributes
|
) ?: StandardClassIds.Any.toConeFlexibleType(emptyArray(), attributes = attributes)
|
||||||
) ?: run {
|
null ->
|
||||||
StandardClassIds.Any.toConeFlexibleType(emptyArray())
|
StandardClassIds.Any.toConeFlexibleType(emptyArray(), attributes = attributes)
|
||||||
}
|
|
||||||
null -> {
|
|
||||||
StandardClassIds.Any.toConeFlexibleType(emptyArray())
|
|
||||||
}
|
|
||||||
else -> error("Strange JavaType: ${this::class.java}")
|
else -> error("Strange JavaType: ${this::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,11 +232,7 @@ private fun ClassId.toConeFlexibleType(
|
|||||||
typeArgumentsForUpper: Array<ConeTypeProjection> = typeArguments,
|
typeArgumentsForUpper: Array<ConeTypeProjection> = typeArguments,
|
||||||
attributes: ConeAttributes = ConeAttributes.Empty
|
attributes: ConeAttributes = ConeAttributes.Empty
|
||||||
) = ConeFlexibleType(
|
) = ConeFlexibleType(
|
||||||
toConeKotlinType(
|
toConeKotlinType(typeArguments, isNullable = false, attributes),
|
||||||
typeArguments,
|
|
||||||
isNullable = false,
|
|
||||||
attributes
|
|
||||||
),
|
|
||||||
toConeKotlinType(typeArgumentsForUpper, isNullable = true, attributes)
|
toConeKotlinType(typeArgumentsForUpper, isNullable = true, attributes)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -276,7 +247,6 @@ private fun JavaClassifierType.toConeKotlinTypeWithoutEnhancement(
|
|||||||
val lowerBound = toConeKotlinTypeForFlexibleBound(
|
val lowerBound = toConeKotlinTypeForFlexibleBound(
|
||||||
session,
|
session,
|
||||||
javaTypeParameterStack,
|
javaTypeParameterStack,
|
||||||
isLowerBound = true,
|
|
||||||
forTypeParameterBounds,
|
forTypeParameterBounds,
|
||||||
isForSupertypes,
|
isForSupertypes,
|
||||||
forAnnotationMember = forAnnotationMember,
|
forAnnotationMember = forAnnotationMember,
|
||||||
@@ -289,7 +259,6 @@ private fun JavaClassifierType.toConeKotlinTypeWithoutEnhancement(
|
|||||||
toConeKotlinTypeForFlexibleBound(
|
toConeKotlinTypeForFlexibleBound(
|
||||||
session,
|
session,
|
||||||
javaTypeParameterStack,
|
javaTypeParameterStack,
|
||||||
isLowerBound = false,
|
|
||||||
forTypeParameterBounds,
|
forTypeParameterBounds,
|
||||||
isForSupertypes,
|
isForSupertypes,
|
||||||
lowerBound,
|
lowerBound,
|
||||||
@@ -398,7 +367,6 @@ private fun getErasedVersionOfFirstUpperBound(
|
|||||||
private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
javaTypeParameterStack: JavaTypeParameterStack,
|
javaTypeParameterStack: JavaTypeParameterStack,
|
||||||
isLowerBound: Boolean,
|
|
||||||
forTypeParameterBounds: Boolean,
|
forTypeParameterBounds: Boolean,
|
||||||
isForSupertypes: Boolean,
|
isForSupertypes: Boolean,
|
||||||
lowerBound: ConeLookupTagBasedType? = null,
|
lowerBound: ConeLookupTagBasedType? = null,
|
||||||
@@ -414,15 +382,13 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
|||||||
JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!)
|
JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!)
|
||||||
} ?: classifier.classId!!
|
} ?: classifier.classId!!
|
||||||
|
|
||||||
if (isLowerBound || argumentsMakeSenseOnlyForMutableContainer(classId, session)) {
|
if (lowerBound == null || argumentsMakeSenseOnlyForMutableContainer(classId, session)) {
|
||||||
classId = classId.readOnlyToMutable() ?: classId
|
classId = classId.readOnlyToMutable() ?: classId
|
||||||
}
|
}
|
||||||
|
|
||||||
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
||||||
if (!isLowerBound && !isRaw && lookupTag == lowerBound?.lookupTag) {
|
if (lookupTag == lowerBound?.lookupTag && !isRaw) {
|
||||||
return lookupTag.constructClassType(
|
return lookupTag.constructClassType(lowerBound.typeArguments, isNullable = true, attributes)
|
||||||
lowerBound.typeArguments, isNullable = true
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val mappedTypeArguments = if (isRaw) {
|
val mappedTypeArguments = if (isRaw) {
|
||||||
@@ -433,7 +399,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
|||||||
// to create a proper raw type arguments, we should take class parameters some time
|
// to create a proper raw type arguments, we should take class parameters some time
|
||||||
defaultArgs
|
defaultArgs
|
||||||
} else {
|
} else {
|
||||||
val position = if (isLowerBound) TypeComponentPosition.FLEXIBLE_LOWER else TypeComponentPosition.FLEXIBLE_UPPER
|
val position = if (lowerBound == null) TypeComponentPosition.FLEXIBLE_LOWER else TypeComponentPosition.FLEXIBLE_UPPER
|
||||||
|
|
||||||
val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol
|
val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol
|
||||||
classSymbol?.fir?.createRawArguments(session, defaultArgs, position) ?: defaultArgs
|
classSymbol?.fir?.createRawArguments(session, defaultArgs, position) ?: defaultArgs
|
||||||
@@ -453,19 +419,15 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lookupTag.constructClassType(
|
lookupTag.constructClassType(mappedTypeArguments.toTypedArray(), isNullable = lowerBound != null, attributes)
|
||||||
mappedTypeArguments.toTypedArray(), isNullable = !isLowerBound, attributes
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
is JavaTypeParameter -> {
|
is JavaTypeParameter -> {
|
||||||
val symbol = javaTypeParameterStack[classifier]
|
val symbol = javaTypeParameterStack[classifier]
|
||||||
ConeTypeParameterTypeImpl(symbol.toLookupTag(), isNullable = !isLowerBound)
|
ConeTypeParameterTypeImpl(symbol.toLookupTag(), isNullable = lowerBound != null, attributes)
|
||||||
}
|
}
|
||||||
null -> {
|
null -> {
|
||||||
val classId = ClassId.topLevel(FqName(this.classifierQualifiedName))
|
val classId = ClassId.topLevel(FqName(this.classifierQualifiedName))
|
||||||
ConeClassLikeLookupTagImpl(classId).constructClassType(
|
classId.constructClassLikeType(emptyArray(), isNullable = lowerBound != null, attributes)
|
||||||
emptyArray(), isNullable = !isLowerBound, attributes,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
else -> ConeKotlinErrorType(ConeSimpleDiagnostic("Unexpected classifier: $classifier", DiagnosticKind.Java))
|
else -> ConeKotlinErrorType(ConeSimpleDiagnostic("Unexpected classifier: $classifier", DiagnosticKind.Java))
|
||||||
}
|
}
|
||||||
@@ -681,9 +643,7 @@ private fun JavaType?.toConeProjectionWithoutEnhancement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is JavaClassifierType -> toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, isForSupertypes = isForSupertypes)
|
else -> toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, isForSupertypes = isForSupertypes)
|
||||||
is JavaArrayType -> toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, isForSupertypes = isForSupertypes)
|
|
||||||
else -> ConeClassErrorType(ConeSimpleDiagnostic("Unexpected type argument: $this", DiagnosticKind.Java))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-88
@@ -12,16 +12,11 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithoutEnhancement
|
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithoutEnhancement
|
||||||
import org.jetbrains.kotlin.fir.java.toFirJavaTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
|
||||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||||
import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType
|
import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType
|
||||||
import org.jetbrains.kotlin.load.java.JavaDefaultQualifiers
|
import org.jetbrains.kotlin.load.java.JavaDefaultQualifiers
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType
|
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
@@ -38,8 +33,6 @@ internal class EnhancementSignatureParts(
|
|||||||
) {
|
) {
|
||||||
private val isForVarargParameter get() = typeContainer.safeAs<FirValueParameter>()?.isVararg == true
|
private val isForVarargParameter get() = typeContainer.safeAs<FirValueParameter>()?.isVararg == true
|
||||||
|
|
||||||
private val attributesCache = mutableMapOf<FirTypeRef?, ConeAttributes>().withDefault { ConeAttributes.Empty }
|
|
||||||
|
|
||||||
private fun ConeKotlinType.toFqNameUnsafe(): FqNameUnsafe? =
|
private fun ConeKotlinType.toFqNameUnsafe(): FqNameUnsafe? =
|
||||||
((this as? ConeLookupTagBasedType)?.lookupTag as? ConeClassLikeLookupTag)?.classId?.asSingleFqName()?.toUnsafe()
|
((this as? ConeLookupTagBasedType)?.lookupTag as? ConeClassLikeLookupTag)?.classId?.asSingleFqName()?.toUnsafe()
|
||||||
|
|
||||||
@@ -48,7 +41,10 @@ internal class EnhancementSignatureParts(
|
|||||||
predefined: TypeEnhancementInfo? = null,
|
predefined: TypeEnhancementInfo? = null,
|
||||||
forAnnotationMember: Boolean = false
|
forAnnotationMember: Boolean = false
|
||||||
): PartEnhancementResult {
|
): PartEnhancementResult {
|
||||||
val qualifiers = computeIndexedQualifiersForOverride(session)
|
val typeWithoutEnhancement = current.type
|
||||||
|
.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forAnnotationMember)
|
||||||
|
|
||||||
|
val qualifiers = computeIndexedQualifiersForOverride(typeWithoutEnhancement)
|
||||||
|
|
||||||
val qualifiersWithPredefined = predefined?.let {
|
val qualifiersWithPredefined = predefined?.let {
|
||||||
IndexedJavaTypeQualifiers(qualifiers.size) { index ->
|
IndexedJavaTypeQualifiers(qualifiers.size) { index ->
|
||||||
@@ -56,12 +52,6 @@ internal class EnhancementSignatureParts(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeWithoutEnhancement = current.type.toConeKotlinTypeWithoutEnhancement(
|
|
||||||
session,
|
|
||||||
javaTypeParameterStack,
|
|
||||||
forAnnotationMember,
|
|
||||||
attributes = attributesCache.getValue(current)
|
|
||||||
)
|
|
||||||
val containsFunctionN = typeWithoutEnhancement.contains {
|
val containsFunctionN = typeWithoutEnhancement.contains {
|
||||||
if (it is ConeClassErrorType) false
|
if (it is ConeClassErrorType) false
|
||||||
else {
|
else {
|
||||||
@@ -87,43 +77,31 @@ internal class EnhancementSignatureParts(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirTypeRef.toConeKotlinType(session: FirSession): ConeKotlinType? =
|
||||||
|
when (this) {
|
||||||
|
is FirResolvedTypeRef -> type
|
||||||
|
is FirJavaTypeRef -> type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirTypeRef.toIndexed(
|
private fun ConeKotlinType?.toIndexed(context: FirJavaEnhancementContext): List<TypeAndDefaultQualifiers> {
|
||||||
typeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
|
||||||
context: FirJavaEnhancementContext
|
|
||||||
): List<TypeAndDefaultQualifiers> {
|
|
||||||
val list = ArrayList<TypeAndDefaultQualifiers>(1)
|
val list = ArrayList<TypeAndDefaultQualifiers>(1)
|
||||||
|
|
||||||
fun add(type: FirTypeRef?) {
|
fun add(type: ConeKotlinType?) {
|
||||||
// TODO: should use the context from parent type
|
// TODO: should use the context from parent type
|
||||||
val c = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, type?.annotations.orEmpty())
|
val annotations = type?.attributes?.customAnnotations.orEmpty()
|
||||||
|
val c = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, annotations)
|
||||||
list.add(TypeAndDefaultQualifiers(type, c.defaultTypeQualifiers?.get(AnnotationQualifierApplicabilityType.TYPE_USE)))
|
list.add(TypeAndDefaultQualifiers(type, c.defaultTypeQualifiers?.get(AnnotationQualifierApplicabilityType.TYPE_USE)))
|
||||||
|
type?.typeArguments?.forEach { add(it.type) }
|
||||||
when (type) {
|
|
||||||
is FirJavaTypeRef -> {
|
|
||||||
for (arg in type.type.typeArguments()) {
|
|
||||||
add(arg.takeIf { it !is JavaWildcardType }?.toFirJavaTypeRef(context.session, javaTypeParameterStack))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is FirUserTypeRef -> {
|
|
||||||
for (arg in type.qualifier.lastOrNull()?.typeArgumentList?.typeArguments.orEmpty()) {
|
|
||||||
add((arg as? FirTypeProjectionWithVariance)?.typeRef)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is FirResolvedTypeRef -> {
|
|
||||||
for (arg in type.type.typeArguments) {
|
|
||||||
add(arg.type?.let { buildResolvedTypeRef { this.type = it } })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> Unit
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add(this)
|
add(this)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractQualifiers(lower: ConeKotlinType, upper: ConeKotlinType): JavaTypeQualifiers {
|
private fun ConeKotlinType.extractQualifiers(): JavaTypeQualifiers {
|
||||||
|
val lower = lowerBoundIfFlexible()
|
||||||
|
val upper = upperBoundIfFlexible()
|
||||||
val mapping = JavaToKotlinClassMap
|
val mapping = JavaToKotlinClassMap
|
||||||
return JavaTypeQualifiers(
|
return JavaTypeQualifiers(
|
||||||
when {
|
when {
|
||||||
@@ -140,29 +118,6 @@ internal class EnhancementSignatureParts(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef.extractQualifiers(session: FirSession): JavaTypeQualifiers {
|
|
||||||
val (lower, upper) = when (this) {
|
|
||||||
is FirResolvedTypeRef -> {
|
|
||||||
val type = this.type
|
|
||||||
if (type is ConeFlexibleType) {
|
|
||||||
Pair(type.lowerBound, type.upperBound)
|
|
||||||
} else {
|
|
||||||
Pair(type, type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is FirJavaTypeRef -> {
|
|
||||||
val convertedType = type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
|
|
||||||
Pair(
|
|
||||||
convertedType.lowerBoundIfFlexible(),
|
|
||||||
convertedType.upperBoundIfFlexible()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else -> return JavaTypeQualifiers.NONE
|
|
||||||
}
|
|
||||||
|
|
||||||
return extractQualifiers(lower, upper)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun composeAnnotations(first: List<FirAnnotationCall>, second: List<FirAnnotationCall>): List<FirAnnotationCall> {
|
private fun composeAnnotations(first: List<FirAnnotationCall>, second: List<FirAnnotationCall>): List<FirAnnotationCall> {
|
||||||
return when {
|
return when {
|
||||||
first.isEmpty() -> second
|
first.isEmpty() -> second
|
||||||
@@ -171,43 +126,35 @@ internal class EnhancementSignatureParts(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef?.extractQualifiersFromAnnotations(
|
private fun TypeAndDefaultQualifiers.extractQualifiersFromAnnotations(isHeadTypeConstructor: Boolean): JavaTypeQualifiers {
|
||||||
isHeadTypeConstructor: Boolean,
|
val annotations = type?.attributes?.customAnnotations.orEmpty()
|
||||||
defaultQualifiersForType: JavaDefaultQualifiers?
|
val composedAnnotations =
|
||||||
): JavaTypeQualifiers {
|
|
||||||
val composedAnnotation =
|
|
||||||
if (isHeadTypeConstructor && typeContainer != null)
|
if (isHeadTypeConstructor && typeContainer != null)
|
||||||
composeAnnotations(typeContainer.annotations, this?.annotations.orEmpty())
|
composeAnnotations(typeContainer.annotations, annotations)
|
||||||
else
|
else
|
||||||
this?.annotations.orEmpty()
|
annotations
|
||||||
|
|
||||||
val defaultTypeQualifier =
|
val defaultTypeQualifier =
|
||||||
if (isHeadTypeConstructor)
|
if (isHeadTypeConstructor)
|
||||||
context.defaultTypeQualifiers?.get(containerApplicabilityType)
|
context.defaultTypeQualifiers?.get(containerApplicabilityType)
|
||||||
else
|
else
|
||||||
defaultQualifiersForType
|
defaultQualifiers
|
||||||
|
|
||||||
val nullabilityInfo = typeQualifierResolver.extractNullability(composedAnnotation).also {
|
val nullabilityInfo = typeQualifierResolver.extractNullability(composedAnnotations)
|
||||||
if (it?.qualifier == NullabilityQualifier.NOT_NULL) {
|
?: defaultTypeQualifier?.nullabilityQualifier
|
||||||
attributesCache[this] = composedAnnotation.computeTypeAttributesForJavaType()
|
|
||||||
}
|
|
||||||
} ?: defaultTypeQualifier?.nullabilityQualifier
|
|
||||||
|
|
||||||
@Suppress("SimplifyBooleanWithConstants")
|
|
||||||
return JavaTypeQualifiers(
|
return JavaTypeQualifiers(
|
||||||
nullabilityInfo?.qualifier,
|
nullabilityInfo?.qualifier,
|
||||||
typeQualifierResolver.extractMutability(composedAnnotation),
|
typeQualifierResolver.extractMutability(composedAnnotations),
|
||||||
isNotNullTypeParameter = nullabilityInfo?.qualifier == NullabilityQualifier.NOT_NULL && this.isTypeParameterBasedType(),
|
isNotNullTypeParameter = nullabilityInfo?.qualifier == NullabilityQualifier.NOT_NULL &&
|
||||||
|
type?.lowerBoundIfFlexible() is ConeTypeParameterType,
|
||||||
isNullabilityQualifierForWarning = nullabilityInfo?.isForWarningOnly == true
|
isNullabilityQualifierForWarning = nullabilityInfo?.isForWarningOnly == true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef?.isTypeParameterBasedType() =
|
private fun computeIndexedQualifiersForOverride(current: ConeKotlinType?): IndexedJavaTypeQualifiers {
|
||||||
((this as? FirJavaTypeRef)?.type as? JavaClassifierType)?.classifier is JavaTypeParameter
|
val indexedFromSupertypes = fromOverridden.map { it.toConeKotlinType(context.session).toIndexed(context) }
|
||||||
|
val indexedThisType = current.toIndexed(context)
|
||||||
private fun computeIndexedQualifiersForOverride(session: FirSession): IndexedJavaTypeQualifiers {
|
|
||||||
val indexedFromSupertypes = fromOverridden.map { it.toIndexed(typeQualifierResolver, context) }
|
|
||||||
val indexedThisType = current.toIndexed(typeQualifierResolver, context)
|
|
||||||
|
|
||||||
// The covariant case may be hard, e.g. in the superclass the return may be Super<T>, but in the subclass it may be Derived, which
|
// The covariant case may be hard, e.g. in the superclass the return may be Super<T>, but in the subclass it may be Derived, which
|
||||||
// is declared to extend Super<T>, and propagating data here is highly non-trivial, so we only look at the head type constructor
|
// is declared to extend Super<T>, and propagating data here is highly non-trivial, so we only look at the head type constructor
|
||||||
@@ -218,9 +165,8 @@ internal class EnhancementSignatureParts(
|
|||||||
|
|
||||||
val treeSize = if (onlyHeadTypeConstructor) 1 else indexedThisType.size
|
val treeSize = if (onlyHeadTypeConstructor) 1 else indexedThisType.size
|
||||||
val computedResult = Array(treeSize) { index ->
|
val computedResult = Array(treeSize) { index ->
|
||||||
val (type, defaultQualifiers) = indexedThisType[index]
|
val qualifiers = indexedThisType[index].extractQualifiersFromAnnotations(index == 0)
|
||||||
val qualifiers = type.extractQualifiersFromAnnotations(index == 0, defaultQualifiers)
|
val superQualifiers = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type?.extractQualifiers() }
|
||||||
val superQualifiers = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type?.extractQualifiers(session) }
|
|
||||||
qualifiers.computeQualifiersForOverride(superQualifiers, index == 0 && isCovariant, index == 0 && isForVarargParameter)
|
qualifiers.computeQualifiersForOverride(superQualifiers, index == 0 && isCovariant, index == 0 && isForVarargParameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,4 +179,9 @@ internal class EnhancementSignatureParts(
|
|||||||
val wereChanges: Boolean,
|
val wereChanges: Boolean,
|
||||||
val containsFunctionN: Boolean
|
val containsFunctionN: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private data class TypeAndDefaultQualifiers(
|
||||||
|
val type: ConeKotlinType?, // null denotes '*' here
|
||||||
|
val defaultQualifiers: JavaDefaultQualifiers?
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.collectEnumEntries
|
import org.jetbrains.kotlin.fir.declarations.utils.collectEnumEntries
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression
|
||||||
@@ -29,7 +28,6 @@ import org.jetbrains.kotlin.fir.typeContext
|
|||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||||
import org.jetbrains.kotlin.load.java.*
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
|
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaType
|
import org.jetbrains.kotlin.load.java.structure.JavaType
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||||
@@ -224,12 +222,6 @@ private fun ConeClassifierLookupTag.enhanceMutability(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal data class TypeAndDefaultQualifiers(
|
|
||||||
val type: FirTypeRef?, // null denotes '*' here
|
|
||||||
val defaultQualifiers: JavaDefaultQualifiers?
|
|
||||||
)
|
|
||||||
|
|
||||||
internal fun JavaType.typeArguments(): List<JavaType?> = (this as? JavaClassifierType)?.typeArguments.orEmpty()
|
internal fun JavaType.typeArguments(): List<JavaType?> = (this as? JavaClassifierType)?.typeArguments.orEmpty()
|
||||||
|
|
||||||
internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String): FirExpression? {
|
internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String): FirExpression? {
|
||||||
@@ -282,22 +274,3 @@ internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String):
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun List<FirAnnotationCall>.computeTypeAttributesForJavaType(): ConeAttributes =
|
|
||||||
computeTypeAttributes { classId ->
|
|
||||||
when (classId) {
|
|
||||||
CompilerConeAttributes.EnhancedNullability.ANNOTATION_CLASS_ID -> add(CompilerConeAttributes.EnhancedNullability)
|
|
||||||
in NOT_NULL_ANNOTATION_IDS -> add(CompilerConeAttributes.EnhancedNullability)
|
|
||||||
JAVAX_NONNULL_ANNOTATION_ID,
|
|
||||||
JAVAX_CHECKFORNULL_ANNOTATION_ID,
|
|
||||||
COMPATQUAL_NONNULL_ANNOTATION_ID,
|
|
||||||
ANDROIDX_RECENTLY_NON_NULL_ANNOTATION_ID
|
|
||||||
-> add(CompilerConeAttributes.EnhancedNullability)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val NOT_NULL_ANNOTATION_IDS = NOT_NULL_ANNOTATIONS.map { ClassId.topLevel(it) }
|
|
||||||
private val JAVAX_NONNULL_ANNOTATION_ID = ClassId.topLevel(JAVAX_NONNULL_ANNOTATION)
|
|
||||||
private val JAVAX_CHECKFORNULL_ANNOTATION_ID = ClassId.topLevel(JAVAX_CHECKFORNULL_ANNOTATION)
|
|
||||||
private val COMPATQUAL_NONNULL_ANNOTATION_ID = ClassId.topLevel(COMPATQUAL_NONNULL_ANNOTATION)
|
|
||||||
private val ANDROIDX_RECENTLY_NON_NULL_ANNOTATION_ID = ClassId.topLevel(ANDROIDX_RECENTLY_NON_NULL_ANNOTATION)
|
|
||||||
|
|||||||
+21
-24
@@ -44,8 +44,10 @@ fun main(
|
|||||||
|
|
||||||
b: AnnotatedBoundsOfWildcard
|
b: AnnotatedBoundsOfWildcard
|
||||||
): Unit {
|
): Unit {
|
||||||
b.superAsIs(aAnyNotNullNotNullNotNull)
|
// jspecify_nullness_mismatch
|
||||||
b.superAsIs(aAnyNotNullNotNullNull)
|
b.superAsIs(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNotNull<!>)
|
||||||
|
// jspecify_nullness_mismatch
|
||||||
|
b.superAsIs(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNull<!>)
|
||||||
b.superAsIs(aAnyNotNullNullNotNull)
|
b.superAsIs(aAnyNotNullNullNotNull)
|
||||||
b.superAsIs(aAnyNotNullNullNull)
|
b.superAsIs(aAnyNotNullNullNull)
|
||||||
|
|
||||||
@@ -54,18 +56,19 @@ fun main(
|
|||||||
b.superNotNull(aAnyNotNullNullNotNull)
|
b.superNotNull(aAnyNotNullNullNotNull)
|
||||||
b.superNotNull(aAnyNotNullNullNull)
|
b.superNotNull(aAnyNotNullNullNull)
|
||||||
|
|
||||||
b.superNullable(aAnyNotNullNotNullNotNull)
|
// jspecify_nullness_mismatch
|
||||||
b.superNullable(aAnyNotNullNotNullNull)
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNotNull<!>)
|
||||||
b.superNullable(aAnyNotNullNullNotNull)
|
// jspecify_nullness_mismatch
|
||||||
b.superNullable(aAnyNotNullNullNull)
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNull<!>)
|
||||||
|
// jspecify_nullness_mismatch
|
||||||
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNullNotNull<!>)
|
||||||
|
// jspecify_nullness_mismatch
|
||||||
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNullNull<!>)
|
||||||
|
|
||||||
b.extendsAsIs(aNotNullNotNullNotNull)
|
b.extendsAsIs(aNotNullNotNullNotNull)
|
||||||
// jspecify_nullness_mismatch
|
b.extendsAsIs(aNotNullNotNullNull)
|
||||||
b.extendsAsIs(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
b.extendsAsIs(aNotNullNullNotNull)
|
||||||
// jspecify_nullness_mismatch
|
b.extendsAsIs(aNotNullNullNull)
|
||||||
b.extendsAsIs(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
|
||||||
// jspecify_nullness_mismatch
|
|
||||||
b.extendsAsIs(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
|
||||||
|
|
||||||
b.extendsNotNull(aNotNullNotNullNotNull)
|
b.extendsNotNull(aNotNullNotNullNotNull)
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
@@ -76,18 +79,12 @@ fun main(
|
|||||||
b.extendsNotNull(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
b.extendsNotNull(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
||||||
|
|
||||||
b.extendsNullable(aNotNullNotNullNotNull)
|
b.extendsNullable(aNotNullNotNullNotNull)
|
||||||
// jspecify_nullness_mismatch
|
b.extendsNullable(aNotNullNotNullNull)
|
||||||
b.extendsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
b.extendsNullable(aNotNullNullNotNull)
|
||||||
// jspecify_nullness_mismatch
|
b.extendsNullable(aNotNullNullNull)
|
||||||
b.extendsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
|
||||||
// jspecify_nullness_mismatch
|
|
||||||
b.extendsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
|
||||||
|
|
||||||
b.noBounds(aNotNullNotNullNotNull)
|
b.noBounds(aNotNullNotNullNotNull)
|
||||||
// jspecify_nullness_mismatch
|
b.noBounds(aNotNullNotNullNull)
|
||||||
b.noBounds(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
b.noBounds(aNotNullNullNotNull)
|
||||||
// jspecify_nullness_mismatch
|
b.noBounds(aNotNullNullNull)
|
||||||
b.noBounds(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
|
||||||
// jspecify_nullness_mismatch
|
|
||||||
b.noBounds(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
|
||||||
}
|
}
|
||||||
|
|||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
// JSPECIFY_STATE: strict
|
|
||||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
|
||||||
|
|
||||||
// FILE: WildcardsWithDefault.java
|
|
||||||
import org.jspecify.nullness.*;
|
|
||||||
|
|
||||||
@NullMarked
|
|
||||||
public class WildcardsWithDefault {
|
|
||||||
public void noBoundsNotNull(A<?, ?, ?> a) {}
|
|
||||||
public void noBoundsNullable(A<? extends @Nullable Object, ? extends @Nullable Object, ? extends @Nullable Object> a) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: A.java
|
|
||||||
import org.jspecify.nullness.*;
|
|
||||||
|
|
||||||
public class A <T extends Object, E extends @Nullable Object, F extends @NullnessUnspecified Object> {}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
fun main(
|
|
||||||
aNotNullNotNullNotNull: A<Any, Any, Any>,
|
|
||||||
aNotNullNotNullNull: A<Any, Any, Any?>,
|
|
||||||
aNotNullNullNotNull: A<Any, Any?, Any>,
|
|
||||||
aNotNullNullNull: A<Any, Any?, Any?>,
|
|
||||||
b: WildcardsWithDefault
|
|
||||||
): Unit {
|
|
||||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
|
||||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
|
||||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
|
||||||
b.noBoundsNotNull(aNotNullNullNull)
|
|
||||||
|
|
||||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
|
||||||
// jspecify_nullness_mismatch
|
|
||||||
b.noBoundsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
|
||||||
// jspecify_nullness_mismatch
|
|
||||||
b.noBoundsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
|
||||||
// jspecify_nullness_mismatch
|
|
||||||
b.noBoundsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// JSPECIFY_STATE: strict
|
// JSPECIFY_STATE: strict
|
||||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||||
|
|
||||||
|
|||||||
+15
-15
@@ -43,8 +43,8 @@ fun main(
|
|||||||
|
|
||||||
b: AnnotatedBoundsOfWildcard
|
b: AnnotatedBoundsOfWildcard
|
||||||
): Unit {
|
): Unit {
|
||||||
b.superAsIs(aAnyNotNullNotNullNotNull)
|
b.superAsIs(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNotNull<!>)
|
||||||
b.superAsIs(aAnyNotNullNotNullNull)
|
b.superAsIs(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNull<!>)
|
||||||
b.superAsIs(aAnyNotNullNullNotNull)
|
b.superAsIs(aAnyNotNullNullNotNull)
|
||||||
b.superAsIs(aAnyNotNullNullNull)
|
b.superAsIs(aAnyNotNullNullNull)
|
||||||
|
|
||||||
@@ -53,15 +53,15 @@ fun main(
|
|||||||
b.superNotNull(aAnyNotNullNullNotNull)
|
b.superNotNull(aAnyNotNullNullNotNull)
|
||||||
b.superNotNull(aAnyNotNullNullNull)
|
b.superNotNull(aAnyNotNullNullNull)
|
||||||
|
|
||||||
b.superNullable(aAnyNotNullNotNullNotNull)
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNotNull<!>)
|
||||||
b.superNullable(aAnyNotNullNotNullNull)
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNotNullNull<!>)
|
||||||
b.superNullable(aAnyNotNullNullNotNull)
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNullNotNull<!>)
|
||||||
b.superNullable(aAnyNotNullNullNull)
|
b.superNullable(<!ARGUMENT_TYPE_MISMATCH!>aAnyNotNullNullNull<!>)
|
||||||
|
|
||||||
b.extendsAsIs(aNotNullNotNullNotNull)
|
b.extendsAsIs(aNotNullNotNullNotNull)
|
||||||
b.extendsAsIs(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
b.extendsAsIs(aNotNullNotNullNull)
|
||||||
b.extendsAsIs(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
b.extendsAsIs(aNotNullNullNotNull)
|
||||||
b.extendsAsIs(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
b.extendsAsIs(aNotNullNullNull)
|
||||||
|
|
||||||
b.extendsNotNull(aNotNullNotNullNotNull)
|
b.extendsNotNull(aNotNullNotNullNotNull)
|
||||||
b.extendsNotNull(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
b.extendsNotNull(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
||||||
@@ -69,12 +69,12 @@ fun main(
|
|||||||
b.extendsNotNull(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
b.extendsNotNull(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
||||||
|
|
||||||
b.extendsNullable(aNotNullNotNullNotNull)
|
b.extendsNullable(aNotNullNotNullNotNull)
|
||||||
b.extendsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
b.extendsNullable(aNotNullNotNullNull)
|
||||||
b.extendsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
b.extendsNullable(aNotNullNullNotNull)
|
||||||
b.extendsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
b.extendsNullable(aNotNullNullNull)
|
||||||
|
|
||||||
b.noBounds(aNotNullNotNullNotNull)
|
b.noBounds(aNotNullNotNullNotNull)
|
||||||
b.noBounds(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
b.noBounds(aNotNullNotNullNull)
|
||||||
b.noBounds(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
b.noBounds(aNotNullNullNotNull)
|
||||||
b.noBounds(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
b.noBounds(aNotNullNullNull)
|
||||||
}
|
}
|
||||||
|
|||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
// JSPECIFY_STATE: warn
|
|
||||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
|
||||||
|
|
||||||
// FILE: WildcardsWithDefault.java
|
|
||||||
import org.jspecify.nullness.*;
|
|
||||||
|
|
||||||
@NullMarked
|
|
||||||
public class WildcardsWithDefault {
|
|
||||||
public void noBoundsNotNull(A<?, ?, ?> a) {}
|
|
||||||
public void noBoundsNullable(A<? extends @Nullable Object, ? extends @Nullable Object, ? extends @Nullable Object> a) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: A.java
|
|
||||||
import org.jspecify.nullness.*;
|
|
||||||
|
|
||||||
public class A <T extends Object, E extends @Nullable Object, F extends @NullnessUnspecified Object> {}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
fun main(
|
|
||||||
aNotNullNotNullNotNull: A<Any, Any, Any>,
|
|
||||||
aNotNullNotNullNull: A<Any, Any, Any?>,
|
|
||||||
aNotNullNullNotNull: A<Any, Any?, Any>,
|
|
||||||
aNotNullNullNull: A<Any, Any?, Any?>,
|
|
||||||
b: WildcardsWithDefault
|
|
||||||
): Unit {
|
|
||||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
|
||||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
|
||||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
|
||||||
b.noBoundsNotNull(aNotNullNullNull)
|
|
||||||
|
|
||||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
|
||||||
b.noBoundsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
|
||||||
b.noBoundsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNotNull<!>)
|
|
||||||
b.noBoundsNullable(<!ARGUMENT_TYPE_MISMATCH!>aNotNullNullNull<!>)
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// JSPECIFY_STATE: warn
|
// JSPECIFY_STATE: warn
|
||||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||||
|
|
||||||
|
|||||||
compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/notNullVarargsOverrides.fir.kt
Vendored
+2
-2
@@ -9,8 +9,8 @@ public class BaseClass {
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
class A : BaseClass() {
|
class A : BaseClass() {
|
||||||
// org.checkerframework.checker.nullness.qual.NonNull has @Target TYPE_USE, so it affects only elements type
|
// org.checkerframework.checker.nullness.qual.NonNull has @Target TYPE_USE, so it affects only elements type
|
||||||
override fun loadCache(vararg args: Any?) {
|
<!NOTHING_TO_OVERRIDE!>override<!> fun loadCache(vararg args: Any?) {
|
||||||
super.loadCache(*args)
|
super.loadCache(*<!ARGUMENT_TYPE_MISMATCH!>args<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
// SOURCE_RETENTION_ANNOTATIONS
|
|
||||||
// FILE: BaseClass.java
|
|
||||||
import org.checkerframework.checker.nullness.qual.*;
|
|
||||||
|
|
||||||
public class BaseClass {
|
|
||||||
public void loadCache(@Nullable Object... args) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FILE: main.kt
|
|
||||||
class A : BaseClass() {
|
|
||||||
override fun loadCache(vararg args: Any?) {
|
|
||||||
super.loadCache(*args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class B : BaseClass() {
|
|
||||||
// org.checkerframework.checker.nullness.qual.Nullable has @Target TYPE_USE, so it affects only elements type
|
|
||||||
override fun loadCache(vararg args: Any) {
|
|
||||||
super.loadCache(*args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// SOURCE_RETENTION_ANNOTATIONS
|
// SOURCE_RETENTION_ANNOTATIONS
|
||||||
// FILE: BaseClass.java
|
// FILE: BaseClass.java
|
||||||
import org.checkerframework.checker.nullness.qual.*;
|
import org.checkerframework.checker.nullness.qual.*;
|
||||||
|
|||||||
+4
-4
@@ -51,13 +51,13 @@ fun <R> main(a: ReturnType<R>) {
|
|||||||
takeNotNullStringAndNotNullK(x3)
|
takeNotNullStringAndNotNullK(x3)
|
||||||
takeNullableStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x3<!>)
|
takeNullableStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x3<!>)
|
||||||
|
|
||||||
val x4 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<R..R?!>..kotlin.Array<out R..R?!>")!>a.foo4<!>
|
val x4 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<R!!>..kotlin.Array<out R!!>")!>a.foo4<!>
|
||||||
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNotNullK(x4)
|
||||||
takeArrayOfNullableK(x4)
|
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
|
|
||||||
val x5 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<kotlin.String..kotlin.String?!>?..kotlin.Array<out kotlin.String..kotlin.String?!>??")!>a.foo5()<!>
|
val x5 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<kotlin.String?>?..kotlin.Array<out kotlin.String?>??")!>a.foo5()<!>
|
||||||
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
|
|||||||
Vendored
+4
-4
@@ -53,13 +53,13 @@ fun <R> main(a: ReturnTypeWithWarnings<R>) {
|
|||||||
takeNotNullStringAndNotNullK(x3)
|
takeNotNullStringAndNotNullK(x3)
|
||||||
takeNullableStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x3<!>)
|
takeNullableStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x3<!>)
|
||||||
|
|
||||||
val x4 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<R..R?!>..kotlin.Array<out R..R?!>")!>a.foo4<!>
|
val x4 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<R!!>..kotlin.Array<out R!!>")!>a.foo4<!>
|
||||||
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNotNullK(x4)
|
||||||
takeArrayOfNullableK(x4)
|
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
|
|
||||||
val x5 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<kotlin.String..kotlin.String?!>?..kotlin.Array<out kotlin.String..kotlin.String?!>??")!>a.foo5()<!>
|
val x5 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<kotlin.String?>?..kotlin.Array<out kotlin.String?>??")!>a.foo5()<!>
|
||||||
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNotNullString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNullableString(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
|
|||||||
Vendored
+1
-1
@@ -50,7 +50,7 @@ fun <R> main(a: ValueParameter<R>) {
|
|||||||
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNotNullString()<!>)
|
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNotNullString()<!>)
|
||||||
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNullableString()<!>)
|
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNullableString()<!>)
|
||||||
a.foo4(getArrayOfNotNullK())
|
a.foo4(getArrayOfNotNullK())
|
||||||
a.foo4(getArrayOfNullableK())
|
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNullableK()<!>)
|
||||||
|
|
||||||
a.foo5(getArrayOfNotNullString())
|
a.foo5(getArrayOfNotNullString())
|
||||||
a.foo5(getArrayOfNullableString())
|
a.foo5(getArrayOfNullableString())
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ fun <R> main(a: ValueParameterWithWarnings<R>) {
|
|||||||
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNotNullString()<!>)
|
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNotNullString()<!>)
|
||||||
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNullableString()<!>)
|
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNullableString()<!>)
|
||||||
a.foo4(getArrayOfNotNullK())
|
a.foo4(getArrayOfNotNullK())
|
||||||
a.foo4(getArrayOfNullableK())
|
a.foo4(<!ARGUMENT_TYPE_MISMATCH!>getArrayOfNullableK()<!>)
|
||||||
|
|
||||||
a.foo5(getArrayOfNotNullString())
|
a.foo5(getArrayOfNotNullString())
|
||||||
a.foo5(getArrayOfNullableString())
|
a.foo5(getArrayOfNullableString())
|
||||||
|
|||||||
+4
-4
@@ -22,12 +22,12 @@ FILE fqName:<root> fileName:/kt43217.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun get (): kotlin.Double [operator] declared in <root>.A.b.<no name provided>'
|
RETURN type=kotlin.Nothing from='public final fun get (): kotlin.Double [operator] declared in <root>.A.b.<no name provided>'
|
||||||
CONST Double type=kotlin.Double value=0.0
|
CONST Double type=kotlin.Double value=0.0
|
||||||
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:@[EnhancedNullability] @[Override] kotlin.Any [fake_override]
|
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
|
||||||
annotations:
|
annotations:
|
||||||
NotNull(value = <null>)
|
NotNull(value = <null>)
|
||||||
Override
|
Override
|
||||||
overridden:
|
overridden:
|
||||||
public open fun isEqualTo (value: kotlin.Double): @[EnhancedNullability] @[Override] kotlin.Any declared in <root>.DoubleExpression
|
public open fun isEqualTo (value: kotlin.Double): @[EnhancedNullability] kotlin.Any declared in <root>.DoubleExpression
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.DoubleExpression
|
$this: VALUE_PARAMETER name:<this> type:<root>.DoubleExpression
|
||||||
VALUE_PARAMETER name:value index:0 type:kotlin.Double
|
VALUE_PARAMETER name:value index:0 type:kotlin.Double
|
||||||
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.ObservableValue<T of <root>.ObservableValue>, value:@[EnhancedNullability] kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
|
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.ObservableValue<T of <root>.ObservableValue>, value:@[EnhancedNullability] kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
|
||||||
@@ -84,12 +84,12 @@ FILE fqName:<root> fileName:/kt43217.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun get (): kotlin.Double [operator] declared in <root>.C'
|
RETURN type=kotlin.Nothing from='public final fun get (): kotlin.Double [operator] declared in <root>.C'
|
||||||
CONST Double type=kotlin.Double value=0.0
|
CONST Double type=kotlin.Double value=0.0
|
||||||
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:@[EnhancedNullability] @[Override] kotlin.Any [fake_override]
|
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
|
||||||
annotations:
|
annotations:
|
||||||
NotNull(value = <null>)
|
NotNull(value = <null>)
|
||||||
Override
|
Override
|
||||||
overridden:
|
overridden:
|
||||||
public open fun isEqualTo (value: kotlin.Double): @[EnhancedNullability] @[Override] kotlin.Any declared in <root>.DoubleExpression
|
public open fun isEqualTo (value: kotlin.Double): @[EnhancedNullability] kotlin.Any declared in <root>.DoubleExpression
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.DoubleExpression
|
$this: VALUE_PARAMETER name:<this> type:<root>.DoubleExpression
|
||||||
VALUE_PARAMETER name:value index:0 type:kotlin.Double
|
VALUE_PARAMETER name:value index:0 type:kotlin.Double
|
||||||
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.ObservableValue<T of <root>.ObservableValue>, value:@[EnhancedNullability] kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
|
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.ObservableValue<T of <root>.ObservableValue>, value:@[EnhancedNullability] kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
public/*package*/ open class AnnotatedTypeInFun : R|kotlin/Any| {
|
public/*package*/ open class AnnotatedTypeInFun : R|kotlin/Any| {
|
||||||
public/*package*/ open fun foo(@R|test/AnnotatedTypeInFun.Anno|(String(a)) a: R|ft<kotlin/String, kotlin/String?>|, @R|test/AnnotatedTypeInFun.Anno|(String(b)) b: R|ft<kotlin/String, kotlin/String?>|): R|kotlin/Unit|
|
public/*package*/ open fun foo(@R|test/AnnotatedTypeInFun.Anno|(String(a)) a: R|ft<@R|test/AnnotatedTypeInFun.Anno|(String(a)) kotlin/String, @R|test/AnnotatedTypeInFun.Anno|(String(a)) kotlin/String?>|, @R|test/AnnotatedTypeInFun.Anno|(String(b)) b: R|ft<@R|test/AnnotatedTypeInFun.Anno|(String(b)) kotlin/String, @R|test/AnnotatedTypeInFun.Anno|(String(b)) kotlin/String?>|): R|kotlin/Unit|
|
||||||
|
|
||||||
public/*package*/ constructor(): R|test/AnnotatedTypeInFun|
|
public/*package*/ constructor(): R|test/AnnotatedTypeInFun|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
public open class ModalityOfFakeOverrides : R|java/util/AbstractList<ft<kotlin/String, kotlin/String?>>| {
|
public open class ModalityOfFakeOverrides : R|java/util/AbstractList<ft<kotlin/String, kotlin/String?>>| {
|
||||||
@R|java/lang/Override|() @R|org/jetbrains/annotations/NotNull|() public open operator fun get(index: R|kotlin/Int|): R|@EnhancedNullability @R|java/lang/Override|() kotlin/String|
|
@R|java/lang/Override|() @R|org/jetbrains/annotations/NotNull|() public open operator fun get(index: R|kotlin/Int|): R|@EnhancedNullability kotlin/String|
|
||||||
|
|
||||||
public constructor(): R|test/ModalityOfFakeOverrides|
|
public constructor(): R|test/ModalityOfFakeOverrides|
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,10 +1,10 @@
|
|||||||
public abstract interface LoadIterableWithNullability<T : R|ft<kotlin/Any, kotlin/Any?>|> : R|kotlin/Any| {
|
public abstract interface LoadIterableWithNullability<T : R|ft<kotlin/Any, kotlin/Any?>|> : R|kotlin/Any| {
|
||||||
@R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/Mutable|() public abstract fun getIterable(): R|@EnhancedNullability @R|kotlin/annotations/jvm/Mutable|() kotlin/collections/MutableIterable<ft<T, T?>>|
|
@R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/Mutable|() public abstract fun getIterable(): R|@EnhancedNullability kotlin/collections/MutableIterable<ft<T, T?>>|
|
||||||
|
|
||||||
public abstract fun setIterable(@R|kotlin/annotations/jvm/Mutable|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability @R|kotlin/annotations/jvm/Mutable|() kotlin/collections/MutableIterable<ft<T, T?>>|): R|kotlin/Unit|
|
public abstract fun setIterable(@R|kotlin/annotations/jvm/Mutable|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability kotlin/collections/MutableIterable<ft<T, T?>>|): R|kotlin/Unit|
|
||||||
|
|
||||||
@R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/ReadOnly|() public abstract fun getReadOnlyIterable(): R|@EnhancedNullability @R|kotlin/annotations/jvm/ReadOnly|() kotlin/collections/Iterable<ft<T, T?>>|
|
@R|org/jetbrains/annotations/NotNull|() @R|kotlin/annotations/jvm/ReadOnly|() public abstract fun getReadOnlyIterable(): R|@EnhancedNullability kotlin/collections/Iterable<ft<T, T?>>|
|
||||||
|
|
||||||
public abstract fun setReadOnlyIterable(@R|kotlin/annotations/jvm/ReadOnly|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability @R|kotlin/annotations/jvm/ReadOnly|() kotlin/collections/Iterable<ft<T, T?>>|): R|kotlin/Unit|
|
public abstract fun setReadOnlyIterable(@R|kotlin/annotations/jvm/ReadOnly|() @R|org/jetbrains/annotations/NotNull|() Iterable: R|@EnhancedNullability kotlin/collections/Iterable<ft<T, T?>>|): R|kotlin/Unit|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user