FIR: use frontend-independent Java type qualifier computation
This commit is contained in:
-148
@@ -1,148 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.java.enhancement
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
|
||||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
|
||||||
import org.jetbrains.kotlin.fir.java.FirJavaTypeConversionMode
|
|
||||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
|
||||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
|
||||||
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.load.java.AnnotationQualifierApplicabilityType
|
|
||||||
import org.jetbrains.kotlin.load.java.JavaDefaultQualifiers
|
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|
||||||
|
|
||||||
internal class EnhancementSignatureParts(
|
|
||||||
private val typeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
|
||||||
private val typeContainer: FirAnnotationContainer?,
|
|
||||||
private val javaTypeParameterStack: JavaTypeParameterStack,
|
|
||||||
private val current: FirJavaTypeRef,
|
|
||||||
private val fromOverridden: Collection<FirTypeRef>,
|
|
||||||
private val isCovariant: Boolean,
|
|
||||||
private val context: FirJavaEnhancementContext,
|
|
||||||
private val containerApplicabilityType: AnnotationQualifierApplicabilityType
|
|
||||||
) {
|
|
||||||
private val isForVarargParameter get() = typeContainer.safeAs<FirValueParameter>()?.isVararg == true
|
|
||||||
|
|
||||||
private fun ConeKotlinType.toFqNameUnsafe(): FqNameUnsafe? =
|
|
||||||
((this as? ConeLookupTagBasedType)?.lookupTag as? ConeClassLikeLookupTag)?.classId?.asSingleFqName()?.toUnsafe()
|
|
||||||
|
|
||||||
internal fun enhance(
|
|
||||||
session: FirSession,
|
|
||||||
predefined: TypeEnhancementInfo? = null,
|
|
||||||
forAnnotationMember: Boolean = false
|
|
||||||
): FirResolvedTypeRef {
|
|
||||||
val mode = if (forAnnotationMember) FirJavaTypeConversionMode.ANNOTATION_MEMBER else FirJavaTypeConversionMode.DEFAULT
|
|
||||||
val typeWithoutEnhancement = current.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack, mode)
|
|
||||||
val qualifiers = computeIndexedQualifiersForOverride(typeWithoutEnhancement, predefined)
|
|
||||||
return buildResolvedTypeRef {
|
|
||||||
type = typeWithoutEnhancement.enhance(session, qualifiers) ?: typeWithoutEnhancement
|
|
||||||
annotations += current.annotations
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ConeKotlinType?.toIndexed(context: FirJavaEnhancementContext): List<TypeAndDefaultQualifiers> {
|
|
||||||
val list = ArrayList<TypeAndDefaultQualifiers>(1)
|
|
||||||
|
|
||||||
fun add(type: ConeKotlinType?) {
|
|
||||||
// TODO: should use the context from parent type
|
|
||||||
val annotations = type?.attributes?.customAnnotations.orEmpty()
|
|
||||||
val c = context.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, annotations)
|
|
||||||
list.add(TypeAndDefaultQualifiers(type, c.defaultTypeQualifiers?.get(AnnotationQualifierApplicabilityType.TYPE_USE)))
|
|
||||||
type?.typeArguments?.forEach { add(it.type) }
|
|
||||||
}
|
|
||||||
|
|
||||||
add(this)
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ConeKotlinType.extractQualifiers(): JavaTypeQualifiers {
|
|
||||||
val lower = lowerBoundIfFlexible()
|
|
||||||
val upper = upperBoundIfFlexible()
|
|
||||||
val mapping = JavaToKotlinClassMap
|
|
||||||
return JavaTypeQualifiers(
|
|
||||||
when {
|
|
||||||
lower.isMarkedNullable -> NullabilityQualifier.NULLABLE
|
|
||||||
!upper.isMarkedNullable -> NullabilityQualifier.NOT_NULL
|
|
||||||
else -> null
|
|
||||||
},
|
|
||||||
when {
|
|
||||||
mapping.isReadOnly(lower.toFqNameUnsafe()) -> MutabilityQualifier.READ_ONLY
|
|
||||||
mapping.isMutable(upper.toFqNameUnsafe()) -> MutabilityQualifier.MUTABLE
|
|
||||||
else -> null
|
|
||||||
},
|
|
||||||
isNotNullTypeParameter = lower is ConeDefinitelyNotNullType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun composeAnnotations(first: List<FirAnnotationCall>, second: List<FirAnnotationCall>): List<FirAnnotationCall> {
|
|
||||||
return when {
|
|
||||||
first.isEmpty() -> second
|
|
||||||
second.isEmpty() -> first
|
|
||||||
else -> first + second
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun TypeAndDefaultQualifiers.extractQualifiersFromAnnotations(isHeadTypeConstructor: Boolean): JavaTypeQualifiers {
|
|
||||||
val annotations = type?.attributes?.customAnnotations.orEmpty()
|
|
||||||
val composedAnnotations =
|
|
||||||
if (isHeadTypeConstructor && typeContainer != null)
|
|
||||||
composeAnnotations(typeContainer.annotations, annotations)
|
|
||||||
else
|
|
||||||
annotations
|
|
||||||
|
|
||||||
val defaultTypeQualifier =
|
|
||||||
if (isHeadTypeConstructor)
|
|
||||||
context.defaultTypeQualifiers?.get(containerApplicabilityType)
|
|
||||||
else
|
|
||||||
defaultQualifiers
|
|
||||||
|
|
||||||
val nullabilityInfo = typeQualifierResolver.extractNullability(composedAnnotations)
|
|
||||||
?: defaultTypeQualifier?.nullabilityQualifier
|
|
||||||
|
|
||||||
return JavaTypeQualifiers(
|
|
||||||
nullabilityInfo?.qualifier,
|
|
||||||
typeQualifierResolver.extractMutability(composedAnnotations),
|
|
||||||
isNotNullTypeParameter = nullabilityInfo?.qualifier == NullabilityQualifier.NOT_NULL &&
|
|
||||||
type?.lowerBoundIfFlexible() is ConeTypeParameterType,
|
|
||||||
isNullabilityQualifierForWarning = nullabilityInfo?.isForWarningOnly == true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun computeIndexedQualifiersForOverride(current: ConeKotlinType?, predefined: TypeEnhancementInfo?): IndexedJavaTypeQualifiers {
|
|
||||||
val indexedFromSupertypes =
|
|
||||||
fromOverridden.map { it.toConeKotlinTypeProbablyFlexible(context.session, javaTypeParameterStack).toIndexed(context) }
|
|
||||||
val indexedThisType = current.toIndexed(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
|
|
||||||
// is declared to extend Super<T>, and propagating data here is highly non-trivial, so we only look at the head type constructor
|
|
||||||
// (outermost type), unless the type in the subclass is interchangeable with the all the types in superclasses:
|
|
||||||
// e.g. we have (Mutable)List<String!>! in the subclass and { List<String!>, (Mutable)List<String>! } from superclasses
|
|
||||||
// Note that `this` is flexible here, so it's equal to it's bounds
|
|
||||||
val onlyHeadTypeConstructor = isCovariant && fromOverridden.any { true /*equalTypes(it, this)*/ }
|
|
||||||
|
|
||||||
val treeSize = if (onlyHeadTypeConstructor) 1 else indexedThisType.size
|
|
||||||
val computedResult = Array(treeSize) { index ->
|
|
||||||
val qualifiers = indexedThisType[index].extractQualifiersFromAnnotations(index == 0)
|
|
||||||
val superQualifiers = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type?.extractQualifiers() }
|
|
||||||
qualifiers.computeQualifiersForOverride(superQualifiers, index == 0 && isCovariant, index == 0 && isForVarargParameter)
|
|
||||||
}
|
|
||||||
return { index -> predefined?.map?.get(index) ?: computedResult.getOrNull(index) ?: JavaTypeQualifiers.NONE }
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class TypeAndDefaultQualifiers(
|
|
||||||
val type: ConeKotlinType?, // null denotes '*' here
|
|
||||||
val defaultQualifiers: JavaDefaultQualifiers?
|
|
||||||
)
|
|
||||||
}
|
|
||||||
+95
-37
@@ -21,13 +21,17 @@ import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
|||||||
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.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
|
import org.jetbrains.kotlin.fir.java.FirJavaTypeConversionMode
|
||||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
|
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
|
||||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
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.typeEnhancement.*
|
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||||
@@ -35,6 +39,12 @@ import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
|||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.load.java.JavaTypeEnhancementState
|
import org.jetbrains.kotlin.load.java.JavaTypeEnhancementState
|
||||||
|
import org.jetbrains.kotlin.load.java.JavaTypeQualifiersByElementType
|
||||||
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeSystemContext
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class FirSignatureEnhancement(
|
class FirSignatureEnhancement(
|
||||||
@@ -170,7 +180,7 @@ class FirSignatureEnhancement(
|
|||||||
}
|
}
|
||||||
return enhanceMethod(firMethod, original.callableId, name)
|
return enhanceMethod(firMethod, original.callableId, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun enhanceMethod(
|
private fun enhanceMethod(
|
||||||
firMethod: FirFunction,
|
firMethod: FirFunction,
|
||||||
methodId: CallableId,
|
methodId: CallableId,
|
||||||
@@ -309,14 +319,16 @@ class FirSignatureEnhancement(
|
|||||||
overriddenMembers: List<FirCallableDeclaration>,
|
overriddenMembers: List<FirCallableDeclaration>,
|
||||||
memberContext: FirJavaEnhancementContext
|
memberContext: FirJavaEnhancementContext
|
||||||
): FirResolvedTypeRef {
|
): FirResolvedTypeRef {
|
||||||
return ownerFunction.partsForValueParameter(
|
return ownerFunction.enhanceValueParameter(
|
||||||
typeQualifierResolver,
|
typeQualifierResolver,
|
||||||
overriddenMembers,
|
overriddenMembers,
|
||||||
// TODO: check me
|
// TODO: check me
|
||||||
parameterContainer = ownerFunction,
|
parameterContainer = ownerFunction,
|
||||||
methodContext = memberContext,
|
methodContext = memberContext,
|
||||||
typeInSignature = TypeInSignature.Receiver
|
typeInSignature = TypeInSignature.Receiver,
|
||||||
).enhance(session)
|
predefined = null,
|
||||||
|
forAnnotationMember = false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun enhanceValueParameterType(
|
private fun enhanceValueParameterType(
|
||||||
@@ -331,15 +343,13 @@ class FirSignatureEnhancement(
|
|||||||
if (ownerParameter.returnTypeRef is FirResolvedTypeRef) {
|
if (ownerParameter.returnTypeRef is FirResolvedTypeRef) {
|
||||||
return ownerParameter.returnTypeRef as FirResolvedTypeRef
|
return ownerParameter.returnTypeRef as FirResolvedTypeRef
|
||||||
}
|
}
|
||||||
return ownerFunction.partsForValueParameter(
|
return ownerFunction.enhanceValueParameter(
|
||||||
typeQualifierResolver,
|
typeQualifierResolver,
|
||||||
overriddenMembers,
|
overriddenMembers,
|
||||||
parameterContainer = ownerParameter,
|
parameterContainer = ownerParameter,
|
||||||
methodContext = memberContext,
|
methodContext = memberContext,
|
||||||
typeInSignature = TypeInSignature.ValueParameter(hasReceiver, index)
|
typeInSignature = TypeInSignature.ValueParameter(hasReceiver, index),
|
||||||
).enhance(
|
predefined = predefinedEnhancementInfo?.parametersInfo?.getOrNull(index),
|
||||||
session,
|
|
||||||
predefinedEnhancementInfo?.parametersInfo?.getOrNull(index),
|
|
||||||
forAnnotationMember = owner.classKind == ClassKind.ANNOTATION_CLASS
|
forAnnotationMember = owner.classKind == ClassKind.ANNOTATION_CLASS
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -350,7 +360,7 @@ class FirSignatureEnhancement(
|
|||||||
memberContext: FirJavaEnhancementContext,
|
memberContext: FirJavaEnhancementContext,
|
||||||
predefinedEnhancementInfo: PredefinedFunctionEnhancementInfo?
|
predefinedEnhancementInfo: PredefinedFunctionEnhancementInfo?
|
||||||
): FirResolvedTypeRef {
|
): FirResolvedTypeRef {
|
||||||
return owner.parts(
|
return owner.enhance(
|
||||||
typeQualifierResolver,
|
typeQualifierResolver,
|
||||||
overriddenMembers,
|
overriddenMembers,
|
||||||
typeContainer = owner, isCovariant = true,
|
typeContainer = owner, isCovariant = true,
|
||||||
@@ -358,9 +368,9 @@ class FirSignatureEnhancement(
|
|||||||
containerApplicabilityType =
|
containerApplicabilityType =
|
||||||
if (owner is FirJavaField) AnnotationQualifierApplicabilityType.FIELD
|
if (owner is FirJavaField) AnnotationQualifierApplicabilityType.FIELD
|
||||||
else AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE,
|
else AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE,
|
||||||
typeInSignature = TypeInSignature.Return
|
typeInSignature = TypeInSignature.Return,
|
||||||
).enhance(
|
predefined = predefinedEnhancementInfo?.returnTypeInfo,
|
||||||
session, predefinedEnhancementInfo?.returnTypeInfo, forAnnotationMember = this.owner.classKind == ClassKind.ANNOTATION_CLASS
|
forAnnotationMember = this.owner.classKind == ClassKind.ANNOTATION_CLASS
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,14 +398,16 @@ class FirSignatureEnhancement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirFunction.partsForValueParameter(
|
private fun FirFunction.enhanceValueParameter(
|
||||||
typeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
typeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
||||||
overriddenMembers: List<FirCallableDeclaration>,
|
overriddenMembers: List<FirCallableDeclaration>,
|
||||||
// TODO: investigate if it's really can be a null (check properties' with extension overrides in Java)
|
// TODO: investigate if it's really can be a null (check properties' with extension overrides in Java)
|
||||||
parameterContainer: FirAnnotationContainer?,
|
parameterContainer: FirAnnotationContainer?,
|
||||||
methodContext: FirJavaEnhancementContext,
|
methodContext: FirJavaEnhancementContext,
|
||||||
typeInSignature: TypeInSignature
|
typeInSignature: TypeInSignature,
|
||||||
): EnhancementSignatureParts = (this as FirCallableDeclaration).parts(
|
predefined: TypeEnhancementInfo?,
|
||||||
|
forAnnotationMember: Boolean
|
||||||
|
): FirResolvedTypeRef = (this as FirCallableDeclaration).enhance(
|
||||||
typeQualifierResolver,
|
typeQualifierResolver,
|
||||||
overriddenMembers,
|
overriddenMembers,
|
||||||
parameterContainer, false,
|
parameterContainer, false,
|
||||||
@@ -403,33 +415,79 @@ class FirSignatureEnhancement(
|
|||||||
methodContext.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, it.annotations)
|
methodContext.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, it.annotations)
|
||||||
} ?: methodContext,
|
} ?: methodContext,
|
||||||
AnnotationQualifierApplicabilityType.VALUE_PARAMETER,
|
AnnotationQualifierApplicabilityType.VALUE_PARAMETER,
|
||||||
typeInSignature
|
typeInSignature,
|
||||||
|
predefined,
|
||||||
|
forAnnotationMember
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun FirCallableDeclaration.parts(
|
private fun FirCallableDeclaration.enhance(
|
||||||
typeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
typeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
||||||
overriddenMembers: List<FirCallableDeclaration>,
|
overriddenMembers: List<FirCallableDeclaration>,
|
||||||
typeContainer: FirAnnotationContainer?,
|
typeContainer: FirAnnotationContainer?,
|
||||||
isCovariant: Boolean,
|
isCovariant: Boolean,
|
||||||
containerContext: FirJavaEnhancementContext,
|
containerContext: FirJavaEnhancementContext,
|
||||||
containerApplicabilityType: AnnotationQualifierApplicabilityType,
|
containerApplicabilityType: AnnotationQualifierApplicabilityType,
|
||||||
typeInSignature: TypeInSignature
|
typeInSignature: TypeInSignature,
|
||||||
): EnhancementSignatureParts {
|
predefined: TypeEnhancementInfo?,
|
||||||
val typeRef = typeInSignature.getTypeRef(this)
|
forAnnotationMember: Boolean
|
||||||
return EnhancementSignatureParts(
|
): FirResolvedTypeRef {
|
||||||
typeQualifierResolver,
|
val parts = EnhancementSignatureParts(
|
||||||
typeContainer,
|
session, typeQualifierResolver, typeContainer, isCovariant,
|
||||||
javaTypeParameterStack,
|
containerApplicabilityType, containerContext.defaultTypeQualifiers
|
||||||
typeRef as FirJavaTypeRef,
|
|
||||||
overriddenMembers.map {
|
|
||||||
typeInSignature.getTypeRef(it)
|
|
||||||
},
|
|
||||||
isCovariant,
|
|
||||||
// recompute default type qualifiers using type annotations
|
|
||||||
containerContext.copyWithNewDefaultTypeQualifiers(
|
|
||||||
typeQualifierResolver, typeRef.annotations
|
|
||||||
),
|
|
||||||
containerApplicabilityType
|
|
||||||
)
|
)
|
||||||
|
val typeRef = typeInSignature.getTypeRef(this)
|
||||||
|
val mode = if (forAnnotationMember) FirJavaTypeConversionMode.ANNOTATION_MEMBER else FirJavaTypeConversionMode.DEFAULT
|
||||||
|
val typeWithoutEnhancement = typeRef.toConeKotlinType(mode)
|
||||||
|
val typesFromOverridden = overriddenMembers.map { typeInSignature.getTypeRef(it).toConeKotlinType(mode) }
|
||||||
|
val qualifiers = with(parts) { typeWithoutEnhancement.computeIndexedQualifiers(typesFromOverridden, predefined) }
|
||||||
|
return buildResolvedTypeRef {
|
||||||
|
type = typeWithoutEnhancement.enhance(session, qualifiers) ?: typeWithoutEnhancement
|
||||||
|
annotations += typeRef.annotations
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirTypeRef.toConeKotlinType(mode: FirJavaTypeConversionMode): ConeKotlinType =
|
||||||
|
toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack, mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EnhancementSignatureParts(
|
||||||
|
private val session: FirSession,
|
||||||
|
override val annotationTypeQualifierResolver: FirAnnotationTypeQualifierResolver,
|
||||||
|
private val typeContainer: FirAnnotationContainer?,
|
||||||
|
override val isCovariant: Boolean,
|
||||||
|
override val containerApplicabilityType: AnnotationQualifierApplicabilityType,
|
||||||
|
override val containerDefaultTypeQualifiers: JavaTypeQualifiersByElementType?
|
||||||
|
) : AbstractSignatureParts<FirAnnotationCall>() {
|
||||||
|
override val enableImprovementsInStrictMode: Boolean
|
||||||
|
get() = true
|
||||||
|
|
||||||
|
override val skipRawTypeArguments: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
override val containerAnnotations: Iterable<FirAnnotationCall>
|
||||||
|
get() = typeContainer?.annotations ?: emptyList()
|
||||||
|
|
||||||
|
override val containerIsVarargParameter: Boolean
|
||||||
|
get() = typeContainer is FirValueParameter && typeContainer.isVararg
|
||||||
|
|
||||||
|
override val typeSystem: TypeSystemContext
|
||||||
|
get() = session.typeContext
|
||||||
|
|
||||||
|
override val FirAnnotationCall.forceWarning: Boolean
|
||||||
|
get() = false // TODO: force warnings on IDEA external annotations
|
||||||
|
|
||||||
|
override val KotlinTypeMarker.annotations: Iterable<FirAnnotationCall>
|
||||||
|
get() = (this as ConeKotlinType).attributes.customAnnotations
|
||||||
|
|
||||||
|
override val KotlinTypeMarker.fqNameUnsafe: FqNameUnsafe?
|
||||||
|
get() = ((this as? ConeLookupTagBasedType)?.lookupTag as? ConeClassLikeLookupTag)?.classId?.asSingleFqName()?.toUnsafe()
|
||||||
|
|
||||||
|
override val KotlinTypeMarker.enhancedForWarnings: KotlinTypeMarker?
|
||||||
|
get() = null // TODO: implement enhancement for warnings
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isEqual(other: KotlinTypeMarker): Boolean =
|
||||||
|
AbstractTypeChecker.equalTypes(session.typeContext, this, other)
|
||||||
|
|
||||||
|
override val TypeParameterMarker.isFromJava: Boolean
|
||||||
|
get() = (this as ConeTypeParameterLookupTag).symbol.fir.origin == FirDeclarationOrigin.Java
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
|||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
import org.jetbrains.kotlin.utils.extractRadix
|
import org.jetbrains.kotlin.utils.extractRadix
|
||||||
|
|
||||||
typealias IndexedJavaTypeQualifiers = (Int) -> JavaTypeQualifiers
|
|
||||||
|
|
||||||
internal fun ConeKotlinType.enhance(session: FirSession, qualifiers: IndexedJavaTypeQualifiers): ConeKotlinType? =
|
internal fun ConeKotlinType.enhance(session: FirSession, qualifiers: IndexedJavaTypeQualifiers): ConeKotlinType? =
|
||||||
enhanceConeKotlinType(session, qualifiers, 0, mutableListOf<Int>().apply { computeSubtreeSizes(this) })
|
enhanceConeKotlinType(session, qualifiers, 0, mutableListOf<Int>().apply { computeSubtreeSizes(this) })
|
||||||
|
|
||||||
|
|||||||
+6
-10
@@ -15,23 +15,19 @@ public class Test {}
|
|||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||||
// jspecify_nullness_mismatch
|
a1.foo(null)
|
||||||
a1.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
a1.foo(1)
|
a1.foo(1)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch
|
a2.foo(null)
|
||||||
a2.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
a2.foo(1)
|
a2.foo(1)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
|
||||||
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a1.bar(x, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, null)
|
||||||
|
a1.bar(x, null)
|
||||||
a1.bar(x, 1)
|
a1.bar(x, 1)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
|
||||||
a2.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
// jspecify_nullness_mismatch
|
// jspecify_nullness_mismatch
|
||||||
a2.bar(x, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a2.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, null)
|
||||||
|
a2.bar(x, null)
|
||||||
a2.bar(x, 1)
|
a2.bar(x, 1)
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/SelfType.fir.kt
Vendored
+3
-6
@@ -39,15 +39,12 @@ public class CKN extends C<@Nullable CK> {}
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun main(ak: AK, akn: AKN, bk: BK, ck: CK, ckn: CKN): Unit {
|
fun main(ak: AK, akn: AKN, bk: BK, ck: CK, ckn: CKN): Unit {
|
||||||
ak.foo(ak)
|
ak.foo(ak)
|
||||||
// jspecify_nullness_mismatch
|
ak.foo(null)
|
||||||
ak.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
|
|
||||||
// jspecify_nullness_mismatch
|
akn.foo(null)
|
||||||
akn.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
|
|
||||||
bk.foo(bk)
|
bk.foo(bk)
|
||||||
// jspecify_nullness_mismatch
|
bk.foo(null)
|
||||||
bk.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
|
|
||||||
ck.foo(ck)
|
ck.foo(ck)
|
||||||
ck.foo(null)
|
ck.foo(null)
|
||||||
|
|||||||
+2
-4
@@ -30,13 +30,11 @@ fun <T : Test> main(a1: A<Any?>, a2: A<Test>, b1: B<Any?>, b2: B<Test>, x: T): U
|
|||||||
a2.bar<T?>(null)
|
a2.bar<T?>(null)
|
||||||
a2.bar<T>(x)
|
a2.bar<T>(x)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch
|
b1.foo(null)
|
||||||
b1.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
b1.bar<T?>(null)
|
b1.bar<T?>(null)
|
||||||
b1.bar<T>(x)
|
b1.bar<T>(x)
|
||||||
|
|
||||||
// jspecify_nullness_mismatch
|
b2.foo(null)
|
||||||
b2.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
|
||||||
b2.bar<T?>(null)
|
b2.bar<T?>(null)
|
||||||
b2.bar<T>(x)
|
b2.bar<T>(x)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -14,5 +14,5 @@ public class Foo<T extends @Nullable Object> {
|
|||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun test(): Foo<String> {
|
fun test(): Foo<String> {
|
||||||
return <!DEBUG_INFO_EXPRESSION_TYPE("Foo<kotlin.String>")!>Foo.create()<!>
|
return <!DEBUG_INFO_EXPRESSION_TYPE("Foo<kotlin.String..kotlin.String?!>")!>Foo.create()<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -14,17 +14,17 @@ public class Test {}
|
|||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||||
a1.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a1.foo(null)
|
||||||
a1.foo(1)
|
a1.foo(1)
|
||||||
|
|
||||||
a2.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a2.foo(null)
|
||||||
a2.foo(1)
|
a2.foo(1)
|
||||||
|
|
||||||
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, null)
|
||||||
a1.bar(x, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a1.bar(x, null)
|
||||||
a1.bar(x, 1)
|
a1.bar(x, 1)
|
||||||
|
|
||||||
a2.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a2.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, null)
|
||||||
a2.bar(x, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
a2.bar(x, null)
|
||||||
a2.bar(x, 1)
|
a2.bar(x, 1)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -40,12 +40,12 @@ public class CKN extends C<@Nullable CK> {}
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun main(ak: AK, akn: AKN, bk: BK, ck: CK, ckn: CKN): Unit {
|
fun main(ak: AK, akn: AKN, bk: BK, ck: CK, ckn: CKN): Unit {
|
||||||
ak.foo(ak)
|
ak.foo(ak)
|
||||||
ak.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
ak.foo(null)
|
||||||
|
|
||||||
akn.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>) // the corresponding warning/error is present on the Java side
|
akn.foo(null) // the corresponding warning/error is present on the Java side
|
||||||
|
|
||||||
bk.foo(bk)
|
bk.foo(bk)
|
||||||
bk.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
bk.foo(null)
|
||||||
|
|
||||||
ck.foo(ck)
|
ck.foo(ck)
|
||||||
ck.foo(null)
|
ck.foo(null)
|
||||||
|
|||||||
+2
-2
@@ -29,11 +29,11 @@ fun <T : Test> main(a1: A<Any?>, a2: A<Test>, b1: B<Any?>, b2: B<Test>, x: T): U
|
|||||||
a2.bar<T?>(null)
|
a2.bar<T?>(null)
|
||||||
a2.bar<T>(x)
|
a2.bar<T>(x)
|
||||||
|
|
||||||
b1.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
b1.foo(null)
|
||||||
b1.bar<T?>(null)
|
b1.bar<T?>(null)
|
||||||
b1.bar<T>(x)
|
b1.bar<T>(x)
|
||||||
|
|
||||||
b2.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
b2.foo(null)
|
||||||
b2.bar<T?>(null)
|
b2.bar<T?>(null)
|
||||||
b2.bar<T>(x)
|
b2.bar<T>(x)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -51,15 +51,15 @@ 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!!>..kotlin.Array<out 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(x4)
|
takeArrayOfNotNullK(x4)
|
||||||
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
|
|
||||||
val x5 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<kotlin.String?>?..kotlin.Array<out 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(x5)
|
||||||
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNullableK(x5)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+4
-4
@@ -53,15 +53,15 @@ 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!!>..kotlin.Array<out 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(x4)
|
takeArrayOfNotNullK(x4)
|
||||||
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x4<!>)
|
||||||
|
|
||||||
val x5 = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Array<kotlin.String?>?..kotlin.Array<out 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(x5)
|
||||||
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
||||||
takeArrayOfNullableK(<!ARGUMENT_TYPE_MISMATCH!>x5<!>)
|
takeArrayOfNullableK(x5)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -32,9 +32,9 @@ fun testDesugaredForInList() {
|
|||||||
|
|
||||||
fun testForInArrayUnused(j: J) {
|
fun testForInArrayUnused(j: J) {
|
||||||
{ // BLOCK
|
{ // BLOCK
|
||||||
val <iterator>: Iterator<@FlexibleNullability P?> = j.arrayOfNotNull().iterator()
|
val <iterator>: Iterator<@EnhancedNullability P> = j.arrayOfNotNull().iterator()
|
||||||
while (<iterator>.hasNext()) { // BLOCK
|
while (<iterator>.hasNext()) { // BLOCK
|
||||||
val x: @FlexibleNullability P? = <iterator>.next()
|
val x: P = <iterator>.next() /*!! P */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,11 +54,11 @@ fun testForInListUse() {
|
|||||||
|
|
||||||
fun testForInArrayUse(j: J) {
|
fun testForInArrayUse(j: J) {
|
||||||
{ // BLOCK
|
{ // BLOCK
|
||||||
val <iterator>: Iterator<@FlexibleNullability P?> = j.arrayOfNotNull().iterator()
|
val <iterator>: Iterator<@EnhancedNullability P> = j.arrayOfNotNull().iterator()
|
||||||
while (<iterator>.hasNext()) { // BLOCK
|
while (<iterator>.hasNext()) { // BLOCK
|
||||||
val x: @FlexibleNullability P? = <iterator>.next()
|
val x: P = <iterator>.next() /*!! P */
|
||||||
{ // BLOCK
|
{ // BLOCK
|
||||||
use(s = x /*!! @FlexibleNullability P */)
|
use(s = x)
|
||||||
use(s = x)
|
use(s = x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-17
@@ -54,17 +54,18 @@ FILE fqName:<root> fileName:/enhancedNullabilityInForLoop.kt
|
|||||||
VALUE_PARAMETER name:j index:0 type:<root>.J
|
VALUE_PARAMETER name:j index:0 type:<root>.J
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
||||||
VAR FOR_LOOP_ITERATOR name:tmp_2 type:kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> [val]
|
VAR FOR_LOOP_ITERATOR name:tmp_2 type:kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> [val]
|
||||||
CALL 'public final fun iterator (): kotlin.collections.Iterator<T of kotlin.Array> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> origin=null
|
CALL 'public final fun iterator (): kotlin.collections.Iterator<T of kotlin.Array> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> origin=null
|
||||||
$this: CALL 'public open fun arrayOfNotNull (): @[EnhancedNullability] kotlin.Array<out @[FlexibleNullability] <root>.P?> declared in <root>.J' type=@[EnhancedNullability] kotlin.Array<out @[FlexibleNullability] <root>.P?> origin=null
|
$this: CALL 'public open fun arrayOfNotNull (): @[EnhancedNullability] kotlin.Array<out @[EnhancedNullability] <root>.P> declared in <root>.J' type=@[EnhancedNullability] kotlin.Array<out @[EnhancedNullability] <root>.P> origin=null
|
||||||
$this: GET_VAR 'j: <root>.J declared in <root>.testForInArrayUnused' type=<root>.J origin=null
|
$this: GET_VAR 'j: <root>.J declared in <root>.testForInArrayUnused' type=<root>.J origin=null
|
||||||
WHILE label=null origin=FOR_LOOP_INNER_WHILE
|
WHILE label=null origin=FOR_LOOP_INNER_WHILE
|
||||||
condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT
|
condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT
|
||||||
$this: GET_VAR 'val tmp_2: kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> [val] declared in <root>.testForInArrayUnused' type=kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> origin=null
|
$this: GET_VAR 'val tmp_2: kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> [val] declared in <root>.testForInArrayUnused' type=kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> origin=null
|
||||||
body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE
|
body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE
|
||||||
VAR FOR_LOOP_VARIABLE name:x type:@[FlexibleNullability] <root>.P? [val]
|
VAR FOR_LOOP_VARIABLE name:x type:<root>.P [val]
|
||||||
CALL 'public abstract fun next (): T of kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterator' type=@[FlexibleNullability] <root>.P? origin=FOR_LOOP_NEXT
|
TYPE_OP type=<root>.P origin=IMPLICIT_NOTNULL typeOperand=<root>.P
|
||||||
$this: GET_VAR 'val tmp_2: kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> [val] declared in <root>.testForInArrayUnused' type=kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> origin=null
|
CALL 'public abstract fun next (): T of kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterator' type=@[EnhancedNullability] <root>.P origin=FOR_LOOP_NEXT
|
||||||
|
$this: GET_VAR 'val tmp_2: kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> [val] declared in <root>.testForInArrayUnused' type=kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> origin=null
|
||||||
FUN name:testForInListUse visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:testForInListUse visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
||||||
@@ -88,23 +89,23 @@ FILE fqName:<root> fileName:/enhancedNullabilityInForLoop.kt
|
|||||||
VALUE_PARAMETER name:j index:0 type:<root>.J
|
VALUE_PARAMETER name:j index:0 type:<root>.J
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
BLOCK type=kotlin.Unit origin=FOR_LOOP
|
||||||
VAR FOR_LOOP_ITERATOR name:tmp_4 type:kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> [val]
|
VAR FOR_LOOP_ITERATOR name:tmp_4 type:kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> [val]
|
||||||
CALL 'public final fun iterator (): kotlin.collections.Iterator<T of kotlin.Array> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> origin=null
|
CALL 'public final fun iterator (): kotlin.collections.Iterator<T of kotlin.Array> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> origin=null
|
||||||
$this: CALL 'public open fun arrayOfNotNull (): @[EnhancedNullability] kotlin.Array<out @[FlexibleNullability] <root>.P?> declared in <root>.J' type=@[EnhancedNullability] kotlin.Array<out @[FlexibleNullability] <root>.P?> origin=null
|
$this: CALL 'public open fun arrayOfNotNull (): @[EnhancedNullability] kotlin.Array<out @[EnhancedNullability] <root>.P> declared in <root>.J' type=@[EnhancedNullability] kotlin.Array<out @[EnhancedNullability] <root>.P> origin=null
|
||||||
$this: GET_VAR 'j: <root>.J declared in <root>.testForInArrayUse' type=<root>.J origin=null
|
$this: GET_VAR 'j: <root>.J declared in <root>.testForInArrayUse' type=<root>.J origin=null
|
||||||
WHILE label=null origin=FOR_LOOP_INNER_WHILE
|
WHILE label=null origin=FOR_LOOP_INNER_WHILE
|
||||||
condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT
|
condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT
|
||||||
$this: GET_VAR 'val tmp_4: kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> [val] declared in <root>.testForInArrayUse' type=kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> origin=null
|
$this: GET_VAR 'val tmp_4: kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> [val] declared in <root>.testForInArrayUse' type=kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> origin=null
|
||||||
body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE
|
body: BLOCK type=kotlin.Unit origin=FOR_LOOP_INNER_WHILE
|
||||||
VAR FOR_LOOP_VARIABLE name:x type:@[FlexibleNullability] <root>.P? [val]
|
VAR FOR_LOOP_VARIABLE name:x type:<root>.P [val]
|
||||||
CALL 'public abstract fun next (): T of kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterator' type=@[FlexibleNullability] <root>.P? origin=FOR_LOOP_NEXT
|
TYPE_OP type=<root>.P origin=IMPLICIT_NOTNULL typeOperand=<root>.P
|
||||||
$this: GET_VAR 'val tmp_4: kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> [val] declared in <root>.testForInArrayUse' type=kotlin.collections.Iterator<@[FlexibleNullability] <root>.P?> origin=null
|
CALL 'public abstract fun next (): T of kotlin.collections.Iterator [operator] declared in kotlin.collections.Iterator' type=@[EnhancedNullability] <root>.P origin=FOR_LOOP_NEXT
|
||||||
|
$this: GET_VAR 'val tmp_4: kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> [val] declared in <root>.testForInArrayUse' type=kotlin.collections.Iterator<@[EnhancedNullability] <root>.P> origin=null
|
||||||
BLOCK type=kotlin.Unit origin=null
|
BLOCK type=kotlin.Unit origin=null
|
||||||
CALL 'public final fun use (s: <root>.P): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
CALL 'public final fun use (s: <root>.P): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
s: TYPE_OP type=@[FlexibleNullability] <root>.P origin=IMPLICIT_NOTNULL typeOperand=@[FlexibleNullability] <root>.P
|
s: GET_VAR 'val x: <root>.P [val] declared in <root>.testForInArrayUse' type=<root>.P origin=null
|
||||||
GET_VAR 'val x: @[FlexibleNullability] <root>.P? [val] declared in <root>.testForInArrayUse' type=@[FlexibleNullability] <root>.P? origin=null
|
|
||||||
CALL 'public open fun use (s: @[EnhancedNullability] <root>.P): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
|
CALL 'public open fun use (s: @[EnhancedNullability] <root>.P): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
|
||||||
s: GET_VAR 'val x: @[FlexibleNullability] <root>.P? [val] declared in <root>.testForInArrayUse' type=@[FlexibleNullability] <root>.P? origin=null
|
s: GET_VAR 'val x: <root>.P [val] declared in <root>.testForInArrayUse' type=<root>.P origin=null
|
||||||
CLASS INTERFACE name:K modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
|
CLASS INTERFACE name:K modality:ABSTRACT visibility:public superTypes:[kotlin.Any]
|
||||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.K
|
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.K
|
||||||
FUN name:arrayOfNotNull visibility:public modality:ABSTRACT <> ($this:<root>.K) returnType:kotlin.Array<<root>.P>
|
FUN name:arrayOfNotNull visibility:public modality:ABSTRACT <> ($this:<root>.K) returnType:kotlin.Array<<root>.P>
|
||||||
|
|||||||
Reference in New Issue
Block a user