FIR: Rewrite Java type mapping

Previoisly, there were two places where mapping had happened:
- toConeKotlinTypeWithNullability
- enhancePossiblyFlexible

The first one was used for supertypes and bounds and the second one
was used for other signature parts

The main idea is to perform type mapping once to a flexible type,
and then use it as it's needed (it's lower bound, or for the further ehnancement)

Also, this commit fixes flexibility for type arguments, see the tests
This commit is contained in:
Denis Zharkov
2020-02-18 19:53:40 +03:00
parent 748a326104
commit 2ad8488e6a
42 changed files with 452 additions and 358 deletions
@@ -92,7 +92,12 @@ class JavaSymbolProvider(
stack: JavaTypeParameterStack, stack: JavaTypeParameterStack,
) { ) {
for (upperBound in javaTypeParameter.upperBounds) { for (upperBound in javaTypeParameter.upperBounds) {
bounds += upperBound.toFirResolvedTypeRef(this@JavaSymbolProvider.session, stack, nullability = ConeNullability.UNKNOWN) bounds += upperBound.toFirResolvedTypeRef(
this@JavaSymbolProvider.session,
stack,
isForSupertypes = false,
forTypeParameterBounds = true
)
} }
addDefaultBoundIfNecessary() addDefaultBoundIfNecessary()
} }
@@ -260,7 +265,7 @@ class JavaSymbolProvider(
firJavaClass.replaceSuperTypeRefs( firJavaClass.replaceSuperTypeRefs(
javaClass.supertypes.map { supertype -> javaClass.supertypes.map { supertype ->
supertype.toFirResolvedTypeRef( supertype.toFirResolvedTypeRef(
this@JavaSymbolProvider.session, javaTypeParameterStack, typeParametersNullability = ConeNullability.UNKNOWN this@JavaSymbolProvider.session, javaTypeParameterStack, isForSupertypes = true, forTypeParameterBounds = false
) )
} }
) )
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
@@ -24,8 +25,11 @@ import org.jetbrains.kotlin.fir.java.declarations.buildJavaValueParameter
import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.getClassDeclaredCallableSymbols import org.jetbrains.kotlin.fir.resolve.getClassDeclaredCallableSymbols
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -38,6 +42,7 @@ import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
import org.jetbrains.kotlin.fir.types.jvm.buildJavaTypeRef import org.jetbrains.kotlin.fir.types.jvm.buildJavaTypeRef
import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
import org.jetbrains.kotlin.load.java.typeEnhancement.TypeComponentPosition
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance.* import org.jetbrains.kotlin.types.Variance.*
@@ -65,24 +70,17 @@ internal fun ClassId.toConeKotlinType(
return ConeClassLikeTypeImpl(lookupTag, typeArguments, isNullable) return ConeClassLikeTypeImpl(lookupTag, typeArguments, isNullable)
} }
internal fun FirTypeRef.toNotNullConeKotlinType( internal fun FirTypeRef.toConeKotlinTypeProbablyFlexible(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): ConeKotlinType = ): ConeKotlinType =
when (this) { when (this) {
is FirResolvedTypeRef -> type is FirResolvedTypeRef -> type
is FirJavaTypeRef -> { is FirJavaTypeRef -> {
val javaType = type type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
javaType.toNotNullConeKotlinType(session, javaTypeParameterStack)
} }
else -> ConeKotlinErrorType("Unexpected type reference in JavaClassUseSiteMemberScope: ${this::class.java}") else -> ConeKotlinErrorType("Unexpected type reference in JavaClassUseSiteMemberScope: ${this::class.java}")
} }
internal fun JavaType?.toNotNullConeKotlinType(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): ConeKotlinType {
return toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NOT_NULL)
}
internal fun JavaType.toFirJavaTypeRef(session: FirSession, javaTypeParameterStack: JavaTypeParameterStack): FirJavaTypeRef { internal fun JavaType.toFirJavaTypeRef(session: FirSession, javaTypeParameterStack: JavaTypeParameterStack): FirJavaTypeRef {
val annotations = (this as? JavaClassifierType)?.annotations.orEmpty() val annotations = (this as? JavaClassifierType)?.annotations.orEmpty()
return buildJavaTypeRef { return buildJavaTypeRef {
@@ -94,25 +92,29 @@ internal fun JavaType.toFirJavaTypeRef(session: FirSession, javaTypeParameterSta
internal fun JavaClassifierType.toFirResolvedTypeRef( internal fun JavaClassifierType.toFirResolvedTypeRef(
session: FirSession, session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack, javaTypeParameterStack: JavaTypeParameterStack,
nullability: ConeNullability = ConeNullability.NOT_NULL, isForSupertypes: Boolean,
typeParametersNullability: ConeNullability = ConeNullability.NOT_NULL forTypeParameterBounds: Boolean
): FirResolvedTypeRef { ): FirResolvedTypeRef {
val coneType = this.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability, typeParametersNullability) val coneType =
this.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forTypeParameterBounds).run {
if (isForSupertypes)
this.lowerBoundIfFlexible()
else
this
}
return buildResolvedTypeRef { return buildResolvedTypeRef {
type = coneType type = coneType
this@toFirResolvedTypeRef.annotations.mapTo(annotations) { it.toFirAnnotationCall(session, javaTypeParameterStack) } this@toFirResolvedTypeRef.annotations.mapTo(annotations) { it.toFirAnnotationCall(session, javaTypeParameterStack) }
} }
} }
internal fun JavaType?.toConeKotlinTypeWithNullability( internal fun JavaType?.toConeKotlinTypeWithoutEnhancement(
session: FirSession, session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack, javaTypeParameterStack: JavaTypeParameterStack
nullability: ConeNullability,
typeParametersNullability: ConeNullability = ConeNullability.NOT_NULL
): ConeKotlinType { ): ConeKotlinType {
return when (this) { return when (this) {
is JavaClassifierType -> { is JavaClassifierType -> {
toConeKotlinTypeWithNullability(session, nullability, typeParametersNullability, javaTypeParameterStack) toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
} }
is JavaPrimitiveType -> { is JavaPrimitiveType -> {
val primitiveType = type val primitiveType = type
@@ -120,77 +122,204 @@ internal fun JavaType?.toConeKotlinTypeWithNullability(
null -> "Unit" null -> "Unit"
else -> javaName.capitalize() else -> javaName.capitalize()
} }
val classId = StandardClassIds.byName(kotlinPrimitiveName) val classId = StandardClassIds.byName(kotlinPrimitiveName)
classId.toConeKotlinType(emptyArray(), nullability.isNullable) classId.toConeKotlinType(emptyArray(), isNullable = false)
} }
is JavaArrayType -> { is JavaArrayType -> {
val componentType = componentType val componentType = componentType
if (componentType !is JavaPrimitiveType) { if (componentType !is JavaPrimitiveType) {
val classId = StandardClassIds.Array val classId = StandardClassIds.Array
val argumentType = ConeFlexibleType( val argumentType = componentType.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
componentType.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NOT_NULL), classId.toConeFlexibleType(
componentType.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NULLABLE) arrayOf(argumentType),
typeArgumentsForUpper = arrayOf(ConeKotlinTypeProjectionOut(argumentType))
) )
classId.toConeKotlinType(arrayOf(argumentType), nullability.isNullable)
} else { } else {
val javaComponentName = componentType.type?.typeName?.asString()?.capitalize() ?: error("Array of voids") val javaComponentName = componentType.type?.typeName?.asString()?.capitalize() ?: error("Array of voids")
val classId = StandardClassIds.byName(javaComponentName + "Array") val classId = StandardClassIds.byName(javaComponentName + "Array")
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
classId.toConeFlexibleType(emptyArray())
} }
} }
is JavaWildcardType -> bound?.toNotNullConeKotlinType(session, javaTypeParameterStack) ?: run { is JavaWildcardType -> bound?.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) ?: run {
val classId = StandardClassIds.Any StandardClassIds.Any.toConeFlexibleType(emptyArray())
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
} }
null -> { null -> {
val classId = StandardClassIds.Any StandardClassIds.Any.toConeFlexibleType(emptyArray())
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
} }
else -> error("Strange JavaType: ${this::class.java}") else -> error("Strange JavaType: ${this::class.java}")
} }
} }
internal fun JavaClassifierType.toConeKotlinTypeWithNullability( private fun ClassId.toConeFlexibleType(
typeArguments: Array<ConeKotlinTypeProjection>,
typeArgumentsForUpper: Array<ConeKotlinTypeProjection> = typeArguments
) = ConeFlexibleType(
toConeKotlinType(typeArguments, isNullable = false),
toConeKotlinType(typeArgumentsForUpper, isNullable = true)
)
private fun JavaClassifierType.toConeKotlinTypeWithoutEnhancement(
session: FirSession, session: FirSession,
nullability: ConeNullability, javaTypeParameterStack: JavaTypeParameterStack,
typeParametersNullability: ConeNullability, forTypeParameterBounds: Boolean = false
javaTypeParameterStack: JavaTypeParameterStack
): ConeKotlinType { ): ConeKotlinType {
if (nullability == ConeNullability.UNKNOWN) { val lowerBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds)
return ConeFlexibleType( val upperBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = false, forTypeParameterBounds)
toConeKotlinTypeWithNullability(session, ConeNullability.NOT_NULL, typeParametersNullability, javaTypeParameterStack),
toConeKotlinTypeWithNullability(session, ConeNullability.NULLABLE, typeParametersNullability, javaTypeParameterStack) return if (isRaw) ConeRawType(lowerBound, upperBound) else ConeFlexibleType(lowerBound, upperBound)
) }
private fun computeRawProjection(
session: FirSession,
parameter: FirTypeParameter,
attr: TypeComponentPosition,
erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound()
) = when (attr) {
// Raw(List<T>) => (List<Any?>..List<*>)
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
// In the last case upper bound is equal to star projection `Enum<*>`,
// but we want to keep matching tree structure of flexible bounds (at least they should have the same size)
TypeComponentPosition.FLEXIBLE_LOWER -> {
// T : String -> String
// in T : String -> String
// T : Enum<T> -> Enum<*>
erasedUpperBound
} }
TypeComponentPosition.FLEXIBLE_UPPER, TypeComponentPosition.INFLEXIBLE -> {
if (!parameter.variance.allowsOutPosition)
// in T -> Comparable<Nothing>
session.builtinTypes.nothingType.type
else if (erasedUpperBound is ConeClassLikeType &&
erasedUpperBound.lookupTag.toSymbol(session)!!.firUnsafe<FirRegularClass>().typeParameters.isNotEmpty()
)
// T : Enum<E> -> out Enum<*>
ConeKotlinTypeProjectionOut(erasedUpperBound)
else
// T : String -> *
ConeStarProjection
}
}
// Definition:
// ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
private fun FirTypeParameter.getErasedUpperBound(
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
// E.g. `class A<T extends A, F extends A>`
// To prevent recursive calls return defaultValue() instead
potentiallyRecursiveTypeParameter: FirTypeParameter? = null,
defaultValue: (() -> ConeKotlinType) = { ConeKotlinErrorType("Can't compute erased upper bound of type parameter `$this`") }
): ConeKotlinType {
if (this === potentiallyRecursiveTypeParameter) return defaultValue()
val firstUpperBound = this.bounds.first().coneTypeUnsafe<ConeKotlinType>()
return getErasedVersionOfFirstUpperBound(firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
}
private fun getErasedVersionOfFirstUpperBound(
firstUpperBound: ConeKotlinType,
alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
defaultValue: () -> ConeKotlinType
): ConeKotlinType =
when (firstUpperBound) {
is ConeClassLikeType ->
firstUpperBound.withArguments(firstUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
is ConeFlexibleType -> {
val lowerBound =
getErasedVersionOfFirstUpperBound(firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue)
.lowerBoundIfFlexible()
if (firstUpperBound.upperBound is ConeTypeParameterType) {
// Avoid exponential complexity
ConeFlexibleType(
lowerBound,
lowerBound.withNullability(ConeNullability.NULLABLE)
)
} else {
ConeFlexibleType(
lowerBound,
getErasedVersionOfFirstUpperBound(firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue)
)
}
}
is ConeTypeParameterType -> {
val current = firstUpperBound.lookupTag.typeParameterSymbol.fir
if (alreadyVisitedParameters.add(current)) {
val nextUpperBound = current.bounds.first().coneTypeUnsafe<ConeKotlinType>()
getErasedVersionOfFirstUpperBound(nextUpperBound, alreadyVisitedParameters, defaultValue)
} else {
defaultValue()
}
}
else -> error("Unexpected kind of firstUpperBound: $firstUpperBound [${firstUpperBound::class}]")
}
private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
isLowerBound: Boolean,
forTypeParameterBounds: Boolean
): ConeKotlinType {
return when (val classifier = classifier) { return when (val classifier = classifier) {
is JavaClass -> { is JavaClass -> {
//val classId = classifier.classId!! //val classId = classifier.classId!!
var classId = JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!) ?: classifier.classId!! var classId = JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!) ?: classifier.classId!!
classId = classId.readOnlyToMutable() ?: classId
if (isLowerBound) {
classId = classId.readOnlyToMutable() ?: classId
}
val lookupTag = ConeClassLikeLookupTagImpl(classId) val lookupTag = ConeClassLikeLookupTagImpl(classId)
val mappedTypeArguments = when (isRaw) { val mappedTypeArguments = if (isRaw) {
true -> classifier.typeParameters.map { ConeStarProjection }
false -> typeArguments.map { argument -> val defaultArgs = (1..classifier.typeParameters.size).map { ConeStarProjection }
argument.toConeProjection(
session, javaTypeParameterStack, boundTypeParameter = null, nullability = typeParametersNullability if (forTypeParameterBounds) {
// This is not fully correct, but it's a simple fix for some time to avoid recursive definition:
// to create a proper raw type arguments, we should take class parameters some time
defaultArgs
} else {
val classSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol
val position = if (isLowerBound) TypeComponentPosition.FLEXIBLE_LOWER else TypeComponentPosition.FLEXIBLE_UPPER
classSymbol?.fir?.createRawArguments(defaultArgs, position) ?: defaultArgs
}
} else {
typeArguments.map { argument ->
argument.toConeProjectionWithoutEnhancement(
session, javaTypeParameterStack, boundTypeParameter = null
) )
} }
} }
lookupTag.constructClassType( lookupTag.constructClassType(
mappedTypeArguments.toTypedArray(), nullability.isNullable mappedTypeArguments.toTypedArray(), isNullable = !isLowerBound
) )
} }
is JavaTypeParameter -> { is JavaTypeParameter -> {
val symbol = javaTypeParameterStack[classifier] val symbol = javaTypeParameterStack[classifier]
ConeTypeParameterTypeImpl(symbol.toLookupTag(), nullability.isNullable) ConeTypeParameterTypeImpl(symbol.toLookupTag(), isNullable = !isLowerBound)
} }
else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier") else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier")
} }
} }
private fun FirRegularClass.createRawArguments(
defaultArgs: List<ConeStarProjection>,
position: TypeComponentPosition
) = typeParameters.map { typeParameter ->
val erasedUpperBound = typeParameter.getErasedUpperBound {
defaultType().withArguments(defaultArgs.toTypedArray())
}
computeRawProjection(session, typeParameter, position, erasedUpperBound)
}
internal fun JavaAnnotation.toFirAnnotationCall( internal fun JavaAnnotation.toFirAnnotationCall(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): FirAnnotationCall { ): FirAnnotationCall {
@@ -226,11 +355,10 @@ internal fun JavaValueParameter.toFirValueParameter(
} }
} }
internal fun JavaType?.toConeProjection( private fun JavaType?.toConeProjectionWithoutEnhancement(
session: FirSession, session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack, javaTypeParameterStack: JavaTypeParameterStack,
boundTypeParameter: FirTypeParameter?, boundTypeParameter: FirTypeParameter?
nullability: ConeNullability = ConeNullability.NOT_NULL
): ConeKotlinTypeProjection { ): ConeKotlinTypeProjection {
return when (this) { return when (this) {
null -> ConeStarProjection null -> ConeStarProjection
@@ -241,7 +369,7 @@ internal fun JavaType?.toConeProjection(
if (bound == null || parameterVariance != INVARIANT && parameterVariance != argumentVariance) { if (bound == null || parameterVariance != INVARIANT && parameterVariance != argumentVariance) {
ConeStarProjection ConeStarProjection
} else { } else {
val boundType = bound.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability) val boundType = bound.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
if (argumentVariance == OUT_VARIANCE) { if (argumentVariance == OUT_VARIANCE) {
ConeKotlinTypeProjectionOut(boundType) ConeKotlinTypeProjectionOut(boundType)
} else { } else {
@@ -249,7 +377,7 @@ internal fun JavaType?.toConeProjection(
} }
} }
} }
is JavaClassifierType -> toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability) is JavaClassifierType -> toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
else -> ConeClassErrorType("Unexpected type argument: $this") else -> ConeClassErrorType("Unexpected type argument: $this")
} }
} }
@@ -342,7 +470,12 @@ internal fun Any?.createConstant(session: FirSession): FirExpression {
private fun JavaType.toFirResolvedTypeRef( private fun JavaType.toFirResolvedTypeRef(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): FirResolvedTypeRef { ): FirResolvedTypeRef {
if (this is JavaClassifierType) return toFirResolvedTypeRef(session, javaTypeParameterStack) if (this is JavaClassifierType) return toFirResolvedTypeRef(
session,
javaTypeParameterStack,
isForSupertypes = false,
forTypeParameterBounds = false
)
return buildResolvedTypeRef { return buildResolvedTypeRef {
type = ConeClassErrorType("Unexpected JavaType: $this") type = ConeClassErrorType("Unexpected JavaType: $this")
} }
@@ -12,9 +12,8 @@ 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.expressions.classId import org.jetbrains.kotlin.fir.expressions.classId
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithNullability import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithoutEnhancement
import org.jetbrains.kotlin.fir.java.toFirJavaTypeRef import org.jetbrains.kotlin.fir.java.toFirJavaTypeRef
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
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.jvm.FirJavaTypeRef import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
@@ -58,7 +57,8 @@ internal class EnhancementSignatureParts(
} }
} }
val containsFunctionN = current.toNotNullConeKotlinType(session, javaTypeParameterStack).contains { val typeWithoutEnhancement = current.type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
val containsFunctionN = typeWithoutEnhancement.contains {
if (it is ConeClassErrorType) false if (it is ConeClassErrorType) false
else { else {
val classId = it.lookupTag.classId val classId = it.lookupTag.classId
@@ -67,7 +67,10 @@ internal class EnhancementSignatureParts(
} }
} }
val enhancedCurrent = current.enhance(session, javaTypeParameterStack, qualifiersWithPredefined ?: qualifiers) val enhancedCurrent = current.enhance(
session, qualifiersWithPredefined ?: qualifiers,
typeWithoutEnhancement
)
return PartEnhancementResult( return PartEnhancementResult(
enhancedCurrent, wereChanges = true, containsFunctionN = containsFunctionN enhancedCurrent, wereChanges = true, containsFunctionN = containsFunctionN
) )
@@ -150,10 +153,10 @@ internal class EnhancementSignatureParts(
} }
} }
is FirJavaTypeRef -> { is FirJavaTypeRef -> {
val convertedType = type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
Pair( Pair(
// TODO: optimize convertedType.lowerBoundIfFlexible(),
type.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability = ConeNullability.NOT_NULL), convertedType.upperBoundIfFlexible()
type.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability = ConeNullability.NULLABLE)
) )
} }
else -> return JavaTypeQualifiers.NONE else -> return JavaTypeQualifiers.NONE
@@ -16,15 +16,11 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildQualifiedAccessExpressi
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.java.toConeProjection
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
@@ -36,13 +32,14 @@ import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME
import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.load.java.typeEnhancement.* import org.jetbrains.kotlin.load.java.typeEnhancement.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.RawType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.extractRadix import org.jetbrains.kotlin.utils.extractRadix
@@ -56,60 +53,23 @@ internal class IndexedJavaTypeQualifiers(private val data: Array<JavaTypeQualifi
internal fun FirJavaTypeRef.enhance( internal fun FirJavaTypeRef.enhance(
session: FirSession, session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack, qualifiers: IndexedJavaTypeQualifiers,
qualifiers: IndexedJavaTypeQualifiers typeWithoutEnhancement: ConeKotlinType,
): FirResolvedTypeRef { ): FirResolvedTypeRef {
return type.enhancePossiblyFlexible(session, javaTypeParameterStack, annotations, qualifiers, 0) return typeWithoutEnhancement.enhancePossiblyFlexible(session, annotations, qualifiers, 0)
} }
// The index in the lambda is the position of the type component: // The index in the lambda is the position of the type component:
// Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`, // Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`,
// which corresponds to the left-to-right breadth-first walk of the tree representation of the type. // which corresponds to the left-to-right breadth-first walk of the tree representation of the type.
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`. // For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
private fun JavaType?.enhancePossiblyFlexible( private fun ConeKotlinType.enhancePossiblyFlexible(
session: FirSession, session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
annotations: List<FirAnnotationCall>, annotations: List<FirAnnotationCall>,
qualifiers: IndexedJavaTypeQualifiers, qualifiers: IndexedJavaTypeQualifiers,
index: Int index: Int
): FirResolvedTypeRef { ): FirResolvedTypeRef {
val type = this val enhanced = enhanceConeKotlinType(session, qualifiers, index)
val arguments = this?.typeArguments().orEmpty()
val enhanced = when (type) {
is JavaClassifierType -> {
val lowerResult = type.enhanceInflexibleType(
session, javaTypeParameterStack, annotations, arguments, TypeComponentPosition.FLEXIBLE_LOWER, qualifiers, index
)
val upperResult = type.enhanceInflexibleType(
session, javaTypeParameterStack, annotations, arguments, TypeComponentPosition.FLEXIBLE_UPPER, qualifiers, index
)
when {
type.isRaw -> ConeRawType(lowerResult, upperResult)
else -> coneFlexibleOrSimpleType(
session, lowerResult, upperResult, isNotNullTypeParameter = qualifiers(index).isNotNullTypeParameter
)
}
}
is JavaArrayType -> {
val baseEnhanced = type.toNotNullConeKotlinType(session, javaTypeParameterStack)
val upperBound = if (baseEnhanced.typeArguments.isNotEmpty()) {
val typeArgument = baseEnhanced.typeArguments.first() as ConeKotlinType
baseEnhanced.withArguments(arrayOf(ConeKotlinTypeProjectionOut(typeArgument)))
} else {
baseEnhanced
}
coneFlexibleOrSimpleType(
session, baseEnhanced,
upperBound.withNullability(ConeNullability.NULLABLE),
isNotNullTypeParameter = false
)
}
else -> {
type.toNotNullConeKotlinType(session, javaTypeParameterStack)
}
}
return buildResolvedTypeRef { return buildResolvedTypeRef {
this.type = enhanced this.type = enhanced
@@ -117,9 +77,34 @@ private fun JavaType?.enhancePossiblyFlexible(
} }
} }
private fun JavaType?.subtreeSize(): Int { private fun ConeKotlinType.enhanceConeKotlinType(
if (this !is JavaClassifierType) return 1 session: FirSession,
return 1 + typeArguments.sumBy { it?.subtreeSize() ?: 0 } qualifiers: IndexedJavaTypeQualifiers,
index: Int
): ConeKotlinType {
return when (this) {
is ConeFlexibleType -> {
val lowerResult = lowerBound.enhanceInflexibleType(
session, TypeComponentPosition.FLEXIBLE_LOWER, qualifiers, index
)
val upperResult = upperBound.enhanceInflexibleType(
session, TypeComponentPosition.FLEXIBLE_UPPER, qualifiers, index
)
when (this) {
is ConeRawType -> ConeRawType(lowerResult, upperResult)
else -> coneFlexibleOrSimpleType(
session, lowerResult, upperResult, isNotNullTypeParameter = qualifiers(index).isNotNullTypeParameter
)
}
}
is ConeSimpleKotlinType -> enhanceInflexibleType(session, TypeComponentPosition.INFLEXIBLE, qualifiers, index)
else -> this
}
}
private fun ConeKotlinType.subtreeSize(): Int {
return 1 + typeArguments.sumBy { ((it as? ConeKotlinType)?.subtreeSize() ?: 0) + 1 }
} }
private fun coneFlexibleOrSimpleType( private fun coneFlexibleOrSimpleType(
@@ -164,155 +149,43 @@ private fun ClassId.mutableToReadOnly(): ClassId? {
} }
} }
// Definition: private fun ConeKotlinType.enhanceInflexibleType(
// ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
private fun FirTypeParameter.getErasedUpperBound(
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
// E.g. `class A<T extends A, F extends A>`
// To prevent recursive calls return defaultValue() instead
potentiallyRecursiveTypeParameter: FirTypeParameter? = null,
defaultValue: (() -> ConeKotlinType) = { ConeKotlinErrorType("Can't compute erased upper bound of type parameter `$this`") }
): ConeKotlinType {
if (this === potentiallyRecursiveTypeParameter) return defaultValue()
val firstUpperBound = this.bounds.first().coneTypeUnsafe<ConeKotlinType>()
return getErasedVersionOfFirstUpperBound(firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
}
private fun getErasedVersionOfFirstUpperBound(
firstUpperBound: ConeKotlinType,
alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
defaultValue: () -> ConeKotlinType
): ConeKotlinType =
when (firstUpperBound) {
is ConeClassLikeType ->
firstUpperBound.withArguments(firstUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
is ConeFlexibleType -> {
val lowerBound =
getErasedVersionOfFirstUpperBound(firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue)
.lowerBoundIfFlexible()
if (firstUpperBound.upperBound is ConeTypeParameterType) {
// Avoid exponential complexity
ConeFlexibleType(
lowerBound,
lowerBound.withNullability(ConeNullability.NULLABLE)
)
} else {
ConeFlexibleType(
lowerBound,
getErasedVersionOfFirstUpperBound(firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue)
)
}
}
is ConeTypeParameterType -> {
val current = firstUpperBound.lookupTag.typeParameterSymbol.fir
if (alreadyVisitedParameters.add(current)) {
val nextUpperBound = current.bounds.first().coneTypeUnsafe<ConeKotlinType>()
getErasedVersionOfFirstUpperBound(nextUpperBound, alreadyVisitedParameters, defaultValue)
} else {
defaultValue()
}
}
else -> error("Unexpected kind of firstUpperBound: $firstUpperBound [${firstUpperBound::class}]")
}
fun computeProjection(
session: FirSession, session: FirSession,
parameter: FirTypeParameter,
attr: TypeComponentPosition,
erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound()
) = when (attr) {
// Raw(List<T>) => (List<Any?>..List<*>)
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
// In the last case upper bound is equal to star projection `Enum<*>`,
// but we want to keep matching tree structure of flexible bounds (at least they should have the same size)
TypeComponentPosition.FLEXIBLE_LOWER -> {
// T : String -> String
// in T : String -> String
// T : Enum<T> -> Enum<*>
erasedUpperBound
}
TypeComponentPosition.FLEXIBLE_UPPER, TypeComponentPosition.INFLEXIBLE -> {
if (!parameter.variance.allowsOutPosition)
// in T -> Comparable<Nothing>
session.builtinTypes.nothingType.type
else if (erasedUpperBound is ConeClassLikeType &&
erasedUpperBound.lookupTag.toSymbol(session)!!.firUnsafe<FirRegularClass>().typeParameters.isNotEmpty()
)
// T : Enum<E> -> out Enum<*>
ConeKotlinTypeProjectionOut(erasedUpperBound)
else
// T : String -> *
ConeStarProjection
}
}
private fun JavaClassifierType.enhanceInflexibleType(
session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
annotations: List<FirAnnotationCall>,
arguments: List<JavaType?>,
position: TypeComponentPosition, position: TypeComponentPosition,
qualifiers: IndexedJavaTypeQualifiers, qualifiers: IndexedJavaTypeQualifiers,
index: Int index: Int
): ConeKotlinType { ): ConeKotlinType {
val originalTag = when (val classifier = classifier) { require(this !is ConeFlexibleType) {
is JavaClass -> { "$this should not be flexible"
val classId = classifier.classId!!
var mappedId = JavaToKotlinClassMap.mapJavaToKotlin(classId.asSingleFqName())
if (mappedId != null) {
if (position == TypeComponentPosition.FLEXIBLE_LOWER) {
mappedId = mappedId.readOnlyToMutable() ?: mappedId
}
}
val kotlinClassId = mappedId ?: classId
ConeClassLikeLookupTagImpl(kotlinClassId)
}
is JavaTypeParameter -> javaTypeParameterStack[classifier].toLookupTag()
else -> return toNotNullConeKotlinType(session, javaTypeParameterStack)
} }
if (this !is ConeLookupTagBasedType) return this
val originalTag = lookupTag
val effectiveQualifiers = qualifiers(index) val effectiveQualifiers = qualifiers(index)
val enhancedTag = originalTag.enhanceMutability(effectiveQualifiers, position) val enhancedTag = originalTag.enhanceMutability(effectiveQualifiers, position)
val enhancedArguments = if (isRaw) { val enhancedArguments = if (this is RawType) {
val firClassifier = originalTag.toSymbol(session)!!.firUnsafe<FirRegularClass>() // TODO: Support enhancing for raw types
firClassifier.typeParameters.map { typeArguments
val fir = it
val erasedUpperBound = fir.getErasedUpperBound {
firClassifier.defaultType().withArguments(firClassifier.typeParameters.map { ConeStarProjection }.toTypedArray())
}
computeProjection(session, fir, position, erasedUpperBound)
}
} else { } else {
var globalArgIndex = index + 1 var globalArgIndex = index + 1
arguments.mapIndexed { localArgIndex, arg -> typeArguments.mapIndexed { localArgIndex, arg ->
if (arg is JavaWildcardType) { if (arg.kind != ProjectionKind.INVARIANT) {
globalArgIndex++ globalArgIndex++
arg.toConeProjection( arg
session,
javaTypeParameterStack,
((originalTag as? FirBasedSymbol<*>)?.fir as? FirCallableMemberDeclaration<*>)?.typeParameters?.getOrNull(localArgIndex)
)
} else { } else {
val argEnhancedTypeRef = require(arg is ConeKotlinType) { "Should be invariant type: $arg" }
arg.enhancePossiblyFlexible(session, javaTypeParameterStack, annotations, qualifiers, globalArgIndex)
globalArgIndex += arg.subtreeSize() globalArgIndex += arg.subtreeSize()
argEnhancedTypeRef.type.type.toTypeProjection(Variance.INVARIANT) arg.enhanceConeKotlinType(session, qualifiers, globalArgIndex)
} }
} }.toTypedArray()
} }
val enhancedNullability = getEnhancedNullability(effectiveQualifiers, position) val enhancedNullability = getEnhancedNullability(effectiveQualifiers, position)
val enhancedType = enhancedTag.constructType(enhancedArguments.toTypedArray(), enhancedNullability) val enhancedType = enhancedTag.constructType(enhancedArguments, enhancedNullability)
// TODO: why all of these is needed // TODO: why all of these is needed
// val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType // val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.modality import org.jetbrains.kotlin.fir.declarations.modality
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable import org.jetbrains.kotlin.fir.java.enhancement.readOnlyToMutable
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractOverrideChecker import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractOverrideChecker
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
@@ -32,7 +32,7 @@ class JavaOverrideChecker internal constructor(
return candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } return candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it }
} }
if (candidateType is ConeClassLikeType && baseType is ConeTypeParameterType) { if (candidateType is ConeClassLikeType && baseType is ConeTypeParameterType) {
val boundType = baseType.lookupTag.typeParameterSymbol.fir.bounds.singleOrNull()?.toNotNullConeKotlinType( val boundType = baseType.lookupTag.typeParameterSymbol.fir.bounds.singleOrNull()?.toConeKotlinTypeProbablyFlexible(
session, javaTypeParameterStack session, javaTypeParameterStack
) )
if (boundType != null) { if (boundType != null) {
@@ -49,8 +49,8 @@ class JavaOverrideChecker internal constructor(
override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) = override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) =
isEqualTypes( isEqualTypes(
candidateTypeRef.toNotNullConeKotlinType(session, javaTypeParameterStack), candidateTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
baseTypeRef.toNotNullConeKotlinType(session, javaTypeParameterStack), baseTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
substitutor substitutor
) )
@@ -189,10 +189,10 @@ fun ConeClassLikeLookupTag.constructClassType(
return ConeClassLikeTypeImpl(this, typeArguments, isNullable) return ConeClassLikeTypeImpl(this, typeArguments, isNullable)
} }
fun ConeClassifierLookupTag.constructType(typeArguments: Array<ConeKotlinTypeProjection>, isNullable: Boolean): ConeLookupTagBasedType { fun ConeClassifierLookupTag.constructType(typeArguments: Array<out ConeKotlinTypeProjection>, isNullable: Boolean): ConeLookupTagBasedType {
return when (this) { return when (this) {
is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl(this, isNullable) is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl(this, isNullable)
is ConeClassLikeLookupTag -> this.constructClassType(typeArguments, isNullable) is ConeClassLikeLookupTag -> this.constructClassType(typeArguments, isNullable)
else -> error("! ${this::class}") else -> error("! ${this::class}")
} }
} }
@@ -16,7 +16,7 @@ FILE: test.kt
private final val DERIVED_FACTORY: R|DiagnosticFactory0<DerivedElement>| = R|/DiagnosticFactory0.DiagnosticFactory0|<R|DerivedElement|>() private final val DERIVED_FACTORY: R|DiagnosticFactory0<DerivedElement>| = R|/DiagnosticFactory0.DiagnosticFactory0|<R|DerivedElement|>()
private get(): R|DiagnosticFactory0<DerivedElement>| private get(): R|DiagnosticFactory0<DerivedElement>|
public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| { public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| {
lval casted: R|Diagnostic<DerivedElement>| = R|/DERIVED_FACTORY|.R|FakeOverride</DiagnosticFactory.cast: R|Diagnostic<DerivedElement>|>|(R|<local>/d|) lval casted: R|Diagnostic<ft<DerivedElement, DerivedElement?>!>| = R|/DERIVED_FACTORY|.R|FakeOverride</DiagnosticFactory.cast: R|Diagnostic<ft<DerivedElement, DerivedElement?>!>|>|(R|<local>/d|)
lval element: R|DerivedElement| = R|<local>/casted|.R|/Diagnostic.element| lval element: R|DerivedElement| = R|<local>/casted|.R|/Diagnostic.element|
R|/Fix.Fix|(R|<local>/element|) R|/Fix.Fix|(R|<local>/element|)
} }
@@ -0,0 +1,13 @@
// FILE: ContainerUtil.java
import java.util.*;
public class ContainerUtil {
public static <E> List<E> flatten(Iterable<? extends Collection<? extends E>> collections) {
return null;
}
}
// FILE: main.kt
fun main(x: MutableCollection<Set<String>>) {
val y = ContainerUtil.flatten(x)
y[0].length
}
@@ -0,0 +1,5 @@
FILE: main.kt
public final fun main(x: R|kotlin/collections/MutableCollection<kotlin/collections/Set<kotlin/String>>|): R|kotlin/Unit| {
lval y: R|ft<kotlin/collections/MutableList<ft<kotlin/String, kotlin/String?>!>, kotlin/collections/List<ft<kotlin/String, kotlin/String?>!>?>!| = Q|ContainerUtil|.R|/ContainerUtil.flatten|<R|ft<kotlin/String, kotlin/String?>!|>(R|<local>/x|)
R|<local>/y|.R|FakeOverride<kotlin/collections/List.get: R|ft<kotlin/String, kotlin/String?>!|>|(Int(0)).R|kotlin/String.length|
}
@@ -13,7 +13,7 @@ FILE: hashTableWithForEach.kt
public get(): R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>| { public get(): R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>| {
when () { when () {
R|/DEBUG| -> { R|/DEBUG| -> {
^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> { ^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet|<R|ft<kotlin/collections/MutableMap.MutableEntry<K, V>, kotlin/collections/MutableMap.MutableEntry<K, V>?>!|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
this@R|/SomeHashTable|.R|FakeOverride</SomeHashTable.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|K|, value: R|V|): R|kotlin/Unit| { this@R|/SomeHashTable|.R|FakeOverride</SomeHashTable.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|K|, value: R|V|): R|kotlin/Unit| {
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|)) ^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|))
} }
@@ -1,7 +1,7 @@
FILE: MapCompute.kt FILE: MapCompute.kt
public final fun <D> R|kotlin/collections/MutableMap<kotlin/String, kotlin/collections/MutableSet<D>>|.initAndAdd(key: R|kotlin/String|, value: R|D|): R|kotlin/Unit| { public final fun <D> R|kotlin/collections/MutableMap<kotlin/String, kotlin/collections/MutableSet<D>>|.initAndAdd(key: R|kotlin/String|, value: R|D|): R|kotlin/Unit| {
this@R|/initAndAdd|.R|FakeOverride<java/util/Map.compute: R|kotlin/collections/MutableSet<D>?|>|(R|<local>/key|, <L> = compute@fun <anonymous>(_: R|kotlin/String|, maybeValues: R|kotlin/collections/MutableSet<D>|): R|kotlin/collections/MutableSet<D>| { this@R|/initAndAdd|.R|FakeOverride<java/util/Map.compute: R|kotlin/collections/MutableSet<D>?|>|(R|<local>/key|, <L> = compute@fun <anonymous>(_: R|ft<kotlin/String, kotlin/String?>!|, maybeValues: R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>!|): R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>!| {
lval setOfValues: R|kotlin/collections/MutableSet<D>| = when (lval <elvis>: R|kotlin/collections/MutableSet<D>| = R|<local>/maybeValues|) { lval setOfValues: R|kotlin/collections/MutableSet<D>| = when (lval <elvis>: R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>!| = R|<local>/maybeValues|) {
==($subj$, Null(null)) -> { ==($subj$, Null(null)) -> {
R|kotlin/collections/mutableSetOf|<R|D|>() R|kotlin/collections/mutableSetOf|<R|D|>()
} }
@@ -8,5 +8,5 @@ FILE: test.kt
} }
public final fun test(some: R|kotlin/collections/Iterable<kotlin/String>|): R|kotlin/Unit| { public final fun test(some: R|kotlin/collections/Iterable<kotlin/String>|): R|kotlin/Unit| {
lval it: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/some|.R|FakeOverride<kotlin/collections/Iterable.iterator: R|kotlin/collections/Iterator<kotlin/String>|>|() lval it: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/some|.R|FakeOverride<kotlin/collections/Iterable.iterator: R|kotlin/collections/Iterator<kotlin/String>|>|()
lval split: R|java/util/Spliterator<kotlin/String>| = R|<local>/some|.R|FakeOverride<java/lang/Iterable.spliterator: R|java/util/Spliterator<kotlin/String>|>|() lval split: R|java/util/Spliterator<ft<kotlin/String, kotlin/String?>!>| = R|<local>/some|.R|FakeOverride<java/lang/Iterable.spliterator: R|java/util/Spliterator<ft<kotlin/String, kotlin/String?>!>|>|()
} }
@@ -28,7 +28,7 @@ FILE: test.kt
) )
lval otherResult: R|kotlin/String| = R|<local>/map|.R|FakeOverride<kotlin/collections/Map.getOrDefault: R|kotlin/String|>|(String(key), String(value)) lval otherResult: R|kotlin/String| = R|<local>/map|.R|FakeOverride<kotlin/collections/Map.getOrDefault: R|kotlin/String|>|(String(key), String(value))
lval anotherResult: R|kotlin/String?| = R|<local>/map|.R|FakeOverride<java/util/Map.replace: R|kotlin/String?|>|(String(key), String(value)) lval anotherResult: R|kotlin/String?| = R|<local>/map|.R|FakeOverride<java/util/Map.replace: R|kotlin/String?|>|(String(key), String(value))
R|<local>/map|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String|, value: R|kotlin/String|): R|kotlin/Unit| { R|<local>/map|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| {
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|())) R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
R|<local>/key|.R|kotlin/String.length| R|<local>/key|.R|kotlin/String.length|
^ R|<local>/value|.R|kotlin/String.length| ^ R|<local>/value|.R|kotlin/String.length|
@@ -1,4 +1,4 @@
FILE: capturedFlexible.kt FILE: capturedFlexible.kt
public final fun foo(z: R|java/util/zip/ZipFile|): R|kotlin/Unit| { public final fun foo(z: R|java/util/zip/ZipFile|): R|kotlin/Unit| {
R|<local>/z|.R|java/util/zip/ZipFile.entries|().R|kotlin/sequences/asSequence|<R|CapturedType(out java/util/zip/ZipEntry)|>() R|<local>/z|.R|java/util/zip/ZipFile.entries|().R|kotlin/sequences/asSequence|<R|CapturedType(out ft<java/util/zip/ZipEntry, java/util/zip/ZipEntry?>!)|>()
} }
@@ -1,4 +1,4 @@
FILE: useSite.kt FILE: useSite.kt
public final fun foo(holder: R|U|, box: R|Box<kotlin/Int>|): R|kotlin/Int| { public final fun foo(holder: R|U|, box: R|Box<kotlin/Int>|): R|kotlin/Int| {
^foo R|<local>/holder|.R|/U.getValue|<R|kotlin/Int|>(R|<local>/box|) ^foo R|<local>/holder|.R|/U.getValue|<R|ft<kotlin/Int, kotlin/Int?>!|>(R|<local>/box|)
} }
@@ -10,7 +10,7 @@ FILE: typeAliasWithForEach.kt
public final typealias Arguments = R|kotlin/collections/Map<kotlin/String, ArgsInfo>| public final typealias Arguments = R|kotlin/collections/Map<kotlin/String, ArgsInfo>|
public final fun R|Arguments|.deepCopy(): R|Arguments| { public final fun R|Arguments|.deepCopy(): R|Arguments| {
lval result: R|java/util/HashMap<kotlin/String, ArgsInfo>| = R|java/util/HashMap.HashMap|<R|kotlin/String|, R|ArgsInfo|>() lval result: R|java/util/HashMap<kotlin/String, ArgsInfo>| = R|java/util/HashMap.HashMap|<R|kotlin/String|, R|ArgsInfo|>()
this@R|/deepCopy|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|kotlin/String|, value: R|ArgsInfo|): R|kotlin/Unit| { this@R|/deepCopy|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<ArgsInfo, ArgsInfo?>!|): R|kotlin/Unit| {
R|<local>/result|.R|kotlin/collections/set|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<ArgsInfo, ArgsInfo?>!|>(R|<local>/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|<local>/value|)) R|<local>/result|.R|kotlin/collections/set|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<ArgsInfo, ArgsInfo?>!|>(R|<local>/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|<local>/value|))
} }
) )
@@ -1726,4 +1726,35 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
} }
} }
} }
@TestMetadata("compiler/fir/resolve/testData/resolve/stdlib")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Stdlib extends AbstractFirDiagnosticsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInStdlib() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("compiler/fir/resolve/testData/resolve/stdlib/j+k")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class J_k extends AbstractFirDiagnosticsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInJ_k() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/j+k"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("flexibleWildcard.kt")
public void testFlexibleWildcard() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/flexibleWildcard.kt");
}
}
}
} }
@@ -1726,4 +1726,35 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
} }
} }
} }
@TestMetadata("compiler/fir/resolve/testData/resolve/stdlib")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Stdlib extends AbstractFirDiagnosticsWithLightTreeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInStdlib() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("compiler/fir/resolve/testData/resolve/stdlib/j+k")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class J_k extends AbstractFirDiagnosticsWithLightTreeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInJ_k() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/resolve/testData/resolve/stdlib/j+k"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("flexibleWildcard.kt")
public void testFlexibleWildcard() throws Exception {
runTest("compiler/fir/resolve/testData/resolve/stdlib/j+k/flexibleWildcard.kt");
}
}
}
} }
@@ -20,5 +20,5 @@ class In<in F> {
fun test() { fun test() {
A.foo().x() checkType { <!UNRESOLVED_REFERENCE!>_<!><Any?>() } A.foo().x() checkType { <!UNRESOLVED_REFERENCE!>_<!><Any?>() }
A.bar().<!INAPPLICABLE_CANDIDATE!>y<!>(null) A.bar().y(null)
} }
@@ -21,11 +21,11 @@ fun test() {
val platformJ = J.staticJ val platformJ = J.staticJ
platformNN[0] platformNN[0]
platformN[0] <!INAPPLICABLE_CANDIDATE!>platformN[0]<!>
platformJ[0] platformJ[0]
platformNN[0] = 1 platformNN[0] = 1
platformN[0] = 1 <!INAPPLICABLE_CANDIDATE!>platformN[0] = 1<!>
platformJ[0] = 1 platformJ[0] = 1
} }
@@ -21,11 +21,11 @@ fun test() {
val platformJ = J.staticJ val platformJ = J.staticJ
platformNN[0] platformNN[0]
platformN[0] <!INAPPLICABLE_CANDIDATE!>platformN[0]<!>
platformJ[0] platformJ[0]
platformNN[0] = 1 platformNN[0] = 1
platformN[0] = 1 <!INAPPLICABLE_CANDIDATE!>platformN[0] = 1<!>
platformJ[0] = 1 platformJ[0] = 1
} }
+9 -9
View File
@@ -16,19 +16,19 @@ FILE fqName:<root> fileName:/builtinMap.kt
pair: GET_VAR 'pair: kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> origin=null pair: GET_VAR 'pair: kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> origin=null
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CALL 'public final fun apply <T> (block: kotlin.Function1<T of kotlin.apply, kotlin.Unit>): T of kotlin.apply [inline] declared in kotlin' type=java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus> origin=null then: CALL 'public final fun apply <T> (block: kotlin.Function1<T of kotlin.apply, kotlin.Unit>): T of kotlin.apply [inline] declared in kotlin' type=java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?> origin=null
<T>: java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus> <T>: java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?>
$receiver: CONSTRUCTOR_CALL 'public constructor <init> (p0: kotlin.collections.Map<out K of <uninitialized parent>, out V of <uninitialized parent>>?) declared in java.util.LinkedHashMap' type=java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus> origin=null $receiver: CONSTRUCTOR_CALL 'public constructor <init> (p0: kotlin.collections.Map<out K of <uninitialized parent>?, out V of <uninitialized parent>?>?) declared in java.util.LinkedHashMap' type=java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?> origin=null
<class: K>: K1 of <root>.plus <class: K>: K1 of <root>.plus?
<class: V>: V1 of <root>.plus <class: V>: V1 of <root>.plus?
p0: GET_VAR '<this>: kotlin.collections.Map<out K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.collections.Map<out K1 of <root>.plus, V1 of <root>.plus> origin=null p0: GET_VAR '<this>: kotlin.collections.Map<out K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.collections.Map<out K1 of <root>.plus, V1 of <root>.plus> origin=null
block: FUN_EXPR type=kotlin.Function1<java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus>, kotlin.Unit> origin=LAMBDA block: FUN_EXPR type=kotlin.Function1<java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?>, kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus>) returnType:kotlin.Unit FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?>) returnType:kotlin.Unit
$receiver: VALUE_PARAMETER name:<this> type:java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus> $receiver: VALUE_PARAMETER name:<this> type:java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?>
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Unit declared in <root>.plus' RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Unit declared in <root>.plus'
CALL 'public open fun put (p0: K1 of <root>.plus?, p1: V1 of <root>.plus?): V1 of <root>.plus? [operator] declared in java.util.HashMap' type=V1 of <root>.plus? origin=null CALL 'public open fun put (p0: K1 of <root>.plus?, p1: V1 of <root>.plus?): V1 of <root>.plus? [operator] declared in java.util.HashMap' type=V1 of <root>.plus? origin=null
$this: GET_VAR '<this>: java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus> declared in special.<anonymous>' type=java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus> origin=null $this: GET_VAR '<this>: java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?> declared in special.<anonymous>' type=java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?> origin=null
p0: CALL 'public final fun <get-first> (): K1 of <root>.plus declared in kotlin.Pair' type=K1 of <root>.plus origin=null p0: CALL 'public final fun <get-first> (): K1 of <root>.plus declared in kotlin.Pair' type=K1 of <root>.plus origin=null
$this: GET_VAR 'pair: kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> origin=null $this: GET_VAR 'pair: kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> declared in <root>.plus' type=kotlin.Pair<K1 of <root>.plus, V1 of <root>.plus> origin=null
p1: CALL 'public final fun <get-second> (): V1 of <root>.plus declared in kotlin.Pair' type=V1 of <root>.plus origin=null p1: CALL 'public final fun <get-second> (): V1 of <root>.plus declared in kotlin.Pair' type=V1 of <root>.plus origin=null
@@ -130,57 +130,57 @@ FILE fqName:<root> fileName:/enhancedNullabilityInDestructuringAssignment.kt
y: GET_VAR 'val y: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null y: GET_VAR 'val y: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY BLOCK_BODY
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.Q<kotlin.String, kotlin.String>? [val] VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.Q<kotlin.String, kotlin.String?>? [val]
CALL 'public open fun notNullComponents (): <root>.Q<kotlin.String, kotlin.String>? [operator] declared in <root>.J' type=<root>.Q<kotlin.String, kotlin.String>? origin=null CALL 'public open fun notNullComponents (): <root>.Q<kotlin.String, kotlin.String?>? [operator] declared in <root>.J' type=<root>.Q<kotlin.String, kotlin.String?>? origin=null
VAR name:x type:kotlin.String [val] VAR name:x type:kotlin.String [val]
CALL 'public final fun component1 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null CALL 'public final fun component1 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null
$this: GET_VAR 'val tmp_1: <root>.Q<kotlin.String, kotlin.String>? [val] declared in <root>.test2' type=<root>.Q<kotlin.String, kotlin.String>? origin=null $this: GET_VAR 'val tmp_1: <root>.Q<kotlin.String, kotlin.String?>? [val] declared in <root>.test2' type=<root>.Q<kotlin.String, kotlin.String?>? origin=null
VAR name:y type:kotlin.String [val] VAR name:y type:kotlin.String? [val]
CALL 'public final fun component2 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null CALL 'public final fun component2 (): kotlin.String? [operator] declared in <root>.Q' type=kotlin.String? origin=null
$this: GET_VAR 'val tmp_1: <root>.Q<kotlin.String, kotlin.String>? [val] declared in <root>.test2' type=<root>.Q<kotlin.String, kotlin.String>? origin=null $this: GET_VAR 'val tmp_1: <root>.Q<kotlin.String, kotlin.String?>? [val] declared in <root>.test2' type=<root>.Q<kotlin.String, kotlin.String?>? origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: kotlin.String [val] declared in <root>.test2' type=kotlin.String origin=null x: GET_VAR 'val x: kotlin.String [val] declared in <root>.test2' type=kotlin.String origin=null
y: GET_VAR 'val y: kotlin.String [val] declared in <root>.test2' type=kotlin.String origin=null y: GET_VAR 'val y: kotlin.String? [val] declared in <root>.test2' type=kotlin.String? origin=null
FUN name:test2Desugared visibility:public modality:FINAL <> () returnType:kotlin.Unit FUN name:test2Desugared visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY BLOCK_BODY
VAR name:tmp type:<root>.Q<kotlin.String, kotlin.String>? [val] VAR name:tmp type:<root>.Q<kotlin.String, kotlin.String?>? [val]
CALL 'public open fun notNullComponents (): <root>.Q<kotlin.String, kotlin.String>? [operator] declared in <root>.J' type=<root>.Q<kotlin.String, kotlin.String>? origin=null CALL 'public open fun notNullComponents (): <root>.Q<kotlin.String, kotlin.String?>? [operator] declared in <root>.J' type=<root>.Q<kotlin.String, kotlin.String?>? origin=null
VAR name:x type:kotlin.String [val] VAR name:x type:kotlin.String [val]
CALL 'public final fun component1 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null CALL 'public final fun component1 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null
$this: GET_VAR 'val tmp: <root>.Q<kotlin.String, kotlin.String>? [val] declared in <root>.test2Desugared' type=<root>.Q<kotlin.String, kotlin.String>? origin=null $this: GET_VAR 'val tmp: <root>.Q<kotlin.String, kotlin.String?>? [val] declared in <root>.test2Desugared' type=<root>.Q<kotlin.String, kotlin.String?>? origin=null
VAR name:y type:kotlin.String [val] VAR name:y type:kotlin.String? [val]
CALL 'public final fun component2 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null CALL 'public final fun component2 (): kotlin.String? [operator] declared in <root>.Q' type=kotlin.String? origin=null
$this: GET_VAR 'val tmp: <root>.Q<kotlin.String, kotlin.String>? [val] declared in <root>.test2Desugared' type=<root>.Q<kotlin.String, kotlin.String>? origin=null $this: GET_VAR 'val tmp: <root>.Q<kotlin.String, kotlin.String?>? [val] declared in <root>.test2Desugared' type=<root>.Q<kotlin.String, kotlin.String?>? origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: kotlin.String [val] declared in <root>.test2Desugared' type=kotlin.String origin=null x: GET_VAR 'val x: kotlin.String [val] declared in <root>.test2Desugared' type=kotlin.String origin=null
y: GET_VAR 'val y: kotlin.String [val] declared in <root>.test2Desugared' type=kotlin.String origin=null y: GET_VAR 'val y: kotlin.String? [val] declared in <root>.test2Desugared' type=kotlin.String? origin=null
FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit FUN name:test3 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY BLOCK_BODY
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.Q<kotlin.String, kotlin.String> [val] VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.Q<kotlin.String, kotlin.String?> [val]
CALL 'public open fun notNullQAndComponents (): <root>.Q<kotlin.String, kotlin.String> [operator] declared in <root>.J' type=<root>.Q<kotlin.String, kotlin.String> origin=null CALL 'public open fun notNullQAndComponents (): <root>.Q<kotlin.String, kotlin.String?> [operator] declared in <root>.J' type=<root>.Q<kotlin.String, kotlin.String?> origin=null
VAR name:x type:kotlin.String [val] VAR name:x type:kotlin.String [val]
CALL 'public final fun component1 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null CALL 'public final fun component1 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null
$this: GET_VAR 'val tmp_2: <root>.Q<kotlin.String, kotlin.String> [val] declared in <root>.test3' type=<root>.Q<kotlin.String, kotlin.String> origin=null $this: GET_VAR 'val tmp_2: <root>.Q<kotlin.String, kotlin.String?> [val] declared in <root>.test3' type=<root>.Q<kotlin.String, kotlin.String?> origin=null
VAR name:y type:kotlin.String [val] VAR name:y type:kotlin.String? [val]
CALL 'public final fun component2 (): kotlin.String [operator] declared in <root>.Q' type=kotlin.String origin=null CALL 'public final fun component2 (): kotlin.String? [operator] declared in <root>.Q' type=kotlin.String? origin=null
$this: GET_VAR 'val tmp_2: <root>.Q<kotlin.String, kotlin.String> [val] declared in <root>.test3' type=<root>.Q<kotlin.String, kotlin.String> origin=null $this: GET_VAR 'val tmp_2: <root>.Q<kotlin.String, kotlin.String?> [val] declared in <root>.test3' type=<root>.Q<kotlin.String, kotlin.String?> origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: kotlin.String [val] declared in <root>.test3' type=kotlin.String origin=null x: GET_VAR 'val x: kotlin.String [val] declared in <root>.test3' type=kotlin.String origin=null
y: GET_VAR 'val y: kotlin.String [val] declared in <root>.test3' type=kotlin.String origin=null y: GET_VAR 'val y: kotlin.String? [val] declared in <root>.test3' type=kotlin.String? origin=null
FUN name:test4 visibility:public modality:FINAL <> () returnType:kotlin.Unit FUN name:test4 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY BLOCK_BODY
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.collections.IndexedValue<<root>.P> [val] VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.collections.IndexedValue<<root>.P?> [val]
CALL 'public final fun first <T> (): T of kotlin.collections.first declared in kotlin.collections' type=kotlin.collections.IndexedValue<<root>.P> origin=null CALL 'public final fun first <T> (): T of kotlin.collections.first declared in kotlin.collections' type=kotlin.collections.IndexedValue<<root>.P?> origin=null
<T>: kotlin.collections.IndexedValue<<root>.P> <T>: kotlin.collections.IndexedValue<<root>.P?>
$receiver: CALL 'public final fun withIndex <T> (): kotlin.collections.Iterable<kotlin.collections.IndexedValue<T of kotlin.collections.withIndex>> declared in kotlin.collections' type=kotlin.collections.Iterable<kotlin.collections.IndexedValue<<root>.P>> origin=null $receiver: CALL 'public final fun withIndex <T> (): kotlin.collections.Iterable<kotlin.collections.IndexedValue<T of kotlin.collections.withIndex>> declared in kotlin.collections' type=kotlin.collections.Iterable<kotlin.collections.IndexedValue<<root>.P?>> origin=null
<T>: <root>.P <T>: <root>.P?
$receiver: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null $receiver: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P?>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P?>? origin=null
VAR name:x type:kotlin.Int [val] VAR name:x type:kotlin.Int [val]
CALL 'public final fun component1 (): kotlin.Int [operator] declared in kotlin.collections.IndexedValue' type=kotlin.Int origin=null CALL 'public final fun component1 (): kotlin.Int [operator] declared in kotlin.collections.IndexedValue' type=kotlin.Int origin=null
$this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<<root>.P> [val] declared in <root>.test4' type=kotlin.collections.IndexedValue<<root>.P> origin=null $this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<<root>.P?> [val] declared in <root>.test4' type=kotlin.collections.IndexedValue<<root>.P?> origin=null
VAR name:y type:<root>.P [val] VAR name:y type:<root>.P? [val]
CALL 'public final fun component2 (): <root>.P [operator] declared in kotlin.collections.IndexedValue' type=<root>.P origin=null CALL 'public final fun component2 (): <root>.P? [operator] declared in kotlin.collections.IndexedValue' type=<root>.P? origin=null
$this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<<root>.P> [val] declared in <root>.test4' type=kotlin.collections.IndexedValue<<root>.P> origin=null $this: GET_VAR 'val tmp_3: kotlin.collections.IndexedValue<<root>.P?> [val] declared in <root>.test4' type=kotlin.collections.IndexedValue<<root>.P?> origin=null
CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null CALL 'public final fun use (x: kotlin.Any, y: kotlin.Any): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
x: GET_VAR 'val x: kotlin.Int [val] declared in <root>.test4' type=kotlin.Int origin=null x: GET_VAR 'val x: kotlin.Int [val] declared in <root>.test4' type=kotlin.Int origin=null
y: GET_VAR 'val y: <root>.P [val] declared in <root>.test4' type=<root>.P origin=null y: GET_VAR 'val y: <root>.P? [val] declared in <root>.test4' type=<root>.P? origin=null
@@ -5,54 +5,54 @@ FILE fqName:<root> fileName:/enhancedNullabilityInForLoop.kt
FUN name:testForInListUnused visibility:public modality:FINAL <> () returnType:kotlin.Unit FUN name:testForInListUnused 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
VAR FOR_LOOP_ITERATOR name:tmp_0 type:kotlin.collections.MutableIterator<<root>.P> [val] VAR FOR_LOOP_ITERATOR name:tmp_0 type:kotlin.collections.MutableIterator<<root>.P?> [val]
CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P> origin=FOR_LOOP_ITERATOR CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P?> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P?> origin=FOR_LOOP_ITERATOR
$this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null $this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P?>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P?>? 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_0: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListUnused' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val tmp_0: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testForInListUnused' type=kotlin.collections.MutableIterator<<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:<root>.P [val] VAR FOR_LOOP_VARIABLE name:x type:<root>.P? [val]
CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P? origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp_0: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListUnused' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val tmp_0: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testForInListUnused' type=kotlin.collections.MutableIterator<<root>.P?> origin=null
FUN name:testForInListDestructured visibility:public modality:FINAL <> () returnType:kotlin.Unit FUN name:testForInListDestructured 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
VAR FOR_LOOP_ITERATOR name:tmp_1 type:kotlin.collections.MutableIterator<<root>.P> [val] VAR FOR_LOOP_ITERATOR name:tmp_1 type:kotlin.collections.MutableIterator<<root>.P?> [val]
CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P> origin=FOR_LOOP_ITERATOR CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P?> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P?> origin=FOR_LOOP_ITERATOR
$this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null $this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P?>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P?>? 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_1: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListDestructured' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val tmp_1: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testForInListDestructured' type=kotlin.collections.MutableIterator<<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:<destruct> type:<root>.P [val] VAR FOR_LOOP_VARIABLE name:<destruct> type:<root>.P? [val]
CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P? origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp_1: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListDestructured' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val tmp_1: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testForInListDestructured' type=kotlin.collections.MutableIterator<<root>.P?> origin=null
VAR name:x type:kotlin.Int [val] VAR name:x type:kotlin.Int [val]
CALL 'public final fun component1 (): kotlin.Int declared in <root>.P' type=kotlin.Int origin=null CALL 'public final fun component1 (): kotlin.Int declared in <root>.P' type=kotlin.Int origin=null
$this: GET_VAR 'val <destruct>: <root>.P [val] declared in <root>.testForInListDestructured' type=<root>.P origin=null $this: GET_VAR 'val <destruct>: <root>.P? [val] declared in <root>.testForInListDestructured' type=<root>.P? origin=null
VAR name:y type:kotlin.Int [val] VAR name:y type:kotlin.Int [val]
CALL 'public final fun component2 (): kotlin.Int declared in <root>.P' type=kotlin.Int origin=null CALL 'public final fun component2 (): kotlin.Int declared in <root>.P' type=kotlin.Int origin=null
$this: GET_VAR 'val <destruct>: <root>.P [val] declared in <root>.testForInListDestructured' type=<root>.P origin=null $this: GET_VAR 'val <destruct>: <root>.P? [val] declared in <root>.testForInListDestructured' type=<root>.P? origin=null
FUN name:testDesugaredForInList visibility:public modality:FINAL <> () returnType:kotlin.Unit FUN name:testDesugaredForInList visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY BLOCK_BODY
VAR name:iterator type:kotlin.collections.MutableIterator<<root>.P> [val] VAR name:iterator type:kotlin.collections.MutableIterator<<root>.P?> [val]
CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P> origin=null CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P?> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P?> origin=null
$this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null $this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P?>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P?>? origin=null
WHILE label=null origin=WHILE_LOOP WHILE label=null origin=WHILE_LOOP
condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null condition: CALL 'public abstract fun hasNext (): kotlin.Boolean [operator] declared in kotlin.collections.Iterator' type=kotlin.Boolean origin=null
$this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testDesugaredForInList' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testDesugaredForInList' type=kotlin.collections.MutableIterator<<root>.P?> origin=null
body: BLOCK type=kotlin.Unit origin=WHILE_LOOP body: BLOCK type=kotlin.Unit origin=WHILE_LOOP
VAR name:x type:<root>.P [val] VAR name:x type:<root>.P? [val]
CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P origin=null CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P? origin=null
$this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testDesugaredForInList' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testDesugaredForInList' type=kotlin.collections.MutableIterator<<root>.P?> origin=null
FUN name:testForInArrayUnused visibility:public modality:FINAL <> (j:<root>.J) returnType:kotlin.Unit FUN name:testForInArrayUnused visibility:public modality:FINAL <> (j:<root>.J) returnType:kotlin.Unit
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<<root>.P?> [val] VAR FOR_LOOP_ITERATOR name:tmp_2 type:kotlin.collections.Iterator<<root>.P?> [val]
CALL 'public final fun iterator (): kotlin.collections.Iterator<<root>.P?> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<<root>.P?> origin=null CALL 'public final fun iterator (): kotlin.collections.Iterator<<root>.P?> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<<root>.P?> origin=null
$this: CALL 'public open fun arrayOfNotNull (): kotlin.Array<out <root>.P?>? [operator] declared in <root>.J' type=kotlin.Array<out <root>.P?>? origin=null $this: CALL 'public open fun arrayOfNotNull (): kotlin.Array<out <root>.P?> [operator] declared in <root>.J' type=kotlin.Array<out <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
@@ -64,27 +64,27 @@ FILE fqName:<root> fileName:/enhancedNullabilityInForLoop.kt
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
VAR FOR_LOOP_ITERATOR name:tmp_3 type:kotlin.collections.MutableIterator<<root>.P> [val] VAR FOR_LOOP_ITERATOR name:tmp_3 type:kotlin.collections.MutableIterator<<root>.P?> [val]
CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P> origin=FOR_LOOP_ITERATOR CALL 'public abstract fun iterator (): kotlin.collections.MutableIterator<<root>.P?> [operator] declared in kotlin.collections.MutableCollection' type=kotlin.collections.MutableIterator<<root>.P?> origin=FOR_LOOP_ITERATOR
$this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null $this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P?>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P?>? 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_3: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListUse' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val tmp_3: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testForInListUse' type=kotlin.collections.MutableIterator<<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:<root>.P [val] VAR FOR_LOOP_VARIABLE name:x type:<root>.P? [val]
CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.MutableIterator [operator] declared in kotlin.collections.Iterator' type=<root>.P? origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp_3: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListUse' type=kotlin.collections.MutableIterator<<root>.P> origin=null $this: GET_VAR 'val tmp_3: kotlin.collections.MutableIterator<<root>.P?> [val] declared in <root>.testForInListUse' type=kotlin.collections.MutableIterator<<root>.P?> 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: GET_VAR 'val x: <root>.P [val] declared in <root>.testForInListUse' type=<root>.P origin=null s: GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInListUse' type=<root>.P? origin=null
CALL 'public open fun use (s: <root>.P): kotlin.Unit [operator] declared in <root>.J' type=kotlin.Unit origin=null CALL 'public open fun use (s: <root>.P): kotlin.Unit [operator] declared in <root>.J' type=kotlin.Unit origin=null
s: GET_VAR 'val x: <root>.P [val] declared in <root>.testForInListUse' type=<root>.P origin=null s: GET_VAR 'val x: <root>.P? [val] declared in <root>.testForInListUse' type=<root>.P? origin=null
FUN name:testForInArrayUse visibility:public modality:FINAL <> (j:<root>.J) returnType:kotlin.Unit FUN name:testForInArrayUse visibility:public modality:FINAL <> (j:<root>.J) returnType:kotlin.Unit
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<<root>.P?> [val] VAR FOR_LOOP_ITERATOR name:tmp_4 type:kotlin.collections.Iterator<<root>.P?> [val]
CALL 'public final fun iterator (): kotlin.collections.Iterator<<root>.P?> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<<root>.P?> origin=null CALL 'public final fun iterator (): kotlin.collections.Iterator<<root>.P?> [operator] declared in kotlin.Array' type=kotlin.collections.Iterator<<root>.P?> origin=null
$this: CALL 'public open fun arrayOfNotNull (): kotlin.Array<out <root>.P?>? [operator] declared in <root>.J' type=kotlin.Array<out <root>.P?>? origin=null $this: CALL 'public open fun arrayOfNotNull (): kotlin.Array<out <root>.P?> [operator] declared in <root>.J' type=kotlin.Array<out <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
@@ -1,4 +1,4 @@
public open class ClassWithTypePRefNext<R : R|ft<kotlin/collections/MutableIterable<P>, kotlin/collections/MutableIterable<P>?>!|, P> : R|kotlin/Any| { public open class ClassWithTypePRefNext<R : R|ft<kotlin/collections/MutableIterable<ft<P, P?>!>, kotlin/collections/Iterable<ft<P, P?>!>?>!|, P> : R|kotlin/Any| {
public constructor<R : R|ft<kotlin/collections/MutableIterable<P>, kotlin/collections/MutableIterable<P>?>!|, P>(): R|test/ClassWithTypePRefNext<R, P>| public constructor<R : R|ft<kotlin/collections/MutableIterable<ft<P, P?>!>, kotlin/collections/Iterable<ft<P, P?>!>?>!|, P>(): R|test/ClassWithTypePRefNext<R, P>|
} }
@@ -1,4 +1,4 @@
public final class ClassWithTypePRefSelf<P : R|ft<kotlin/Enum<P>, kotlin/Enum<P>?>!|> : R|kotlin/Any| { public final class ClassWithTypePRefSelf<P : R|ft<kotlin/Enum<ft<P, P?>!>, kotlin/Enum<ft<P, P?>!>?>!|> : R|kotlin/Any| {
public constructor<P : R|ft<kotlin/Enum<P>, kotlin/Enum<P>?>!|>(): R|test/ClassWithTypePRefSelf<P>| public constructor<P : R|ft<kotlin/Enum<ft<P, P?>!>, kotlin/Enum<ft<P, P?>!>?>!|>(): R|test/ClassWithTypePRefSelf<P>|
} }
@@ -1,4 +1,4 @@
public final class ClassWithTypePRefSelfAndClass<P : R|ft<test/ClassWithTypePRefSelfAndClass<P>, test/ClassWithTypePRefSelfAndClass<P>?>!|> : R|kotlin/Any| { public final class ClassWithTypePRefSelfAndClass<P : R|ft<test/ClassWithTypePRefSelfAndClass<ft<P, P?>!>, test/ClassWithTypePRefSelfAndClass<ft<P, P?>!>?>!|> : R|kotlin/Any| {
public constructor<P : R|ft<test/ClassWithTypePRefSelfAndClass<P>, test/ClassWithTypePRefSelfAndClass<P>?>!|>(): R|test/ClassWithTypePRefSelfAndClass<P>| public constructor<P : R|ft<test/ClassWithTypePRefSelfAndClass<ft<P, P?>!>, test/ClassWithTypePRefSelfAndClass<ft<P, P?>!>?>!|>(): R|test/ClassWithTypePRefSelfAndClass<P>|
} }
@@ -1,6 +1,6 @@
public abstract interface RemoveRedundantProjectionKind : R|kotlin/Any| { public abstract interface RemoveRedundantProjectionKind : R|kotlin/Any| {
public abstract operator fun f(collection: R|ft<kotlin/collections/MutableCollection<out kotlin/CharSequence>, kotlin/collections/Collection<out kotlin/CharSequence>?>!|): R|kotlin/Unit| public abstract operator fun f(collection: R|ft<kotlin/collections/MutableCollection<out ft<kotlin/CharSequence, kotlin/CharSequence?>!>, kotlin/collections/Collection<out ft<kotlin/CharSequence, kotlin/CharSequence?>!>?>!|): R|kotlin/Unit|
public abstract operator fun f(comparator: R|ft<kotlin/Comparable<in kotlin/CharSequence>, kotlin/Comparable<in kotlin/CharSequence>?>!|): R|kotlin/Unit| public abstract operator fun f(comparator: R|ft<kotlin/Comparable<in ft<kotlin/CharSequence, kotlin/CharSequence?>!>, kotlin/Comparable<in ft<kotlin/CharSequence, kotlin/CharSequence?>!>?>!|): R|kotlin/Unit|
} }
@@ -1,5 +1,5 @@
public open class WildcardBounds : R|kotlin/Any| { public open class WildcardBounds : R|kotlin/Any| {
public/*package*/ open operator fun foo(x: R|ft<test/WildcardBounds.A<out kotlin/CharSequence>, test/WildcardBounds.A<out kotlin/CharSequence>?>!|, y: R|ft<test/WildcardBounds.A<in kotlin/String>, test/WildcardBounds.A<in kotlin/String>?>!|): R|kotlin/Unit| public/*package*/ open operator fun foo(x: R|ft<test/WildcardBounds.A<out ft<kotlin/CharSequence, kotlin/CharSequence?>!>, test/WildcardBounds.A<out ft<kotlin/CharSequence, kotlin/CharSequence?>!>?>!|, y: R|ft<test/WildcardBounds.A<in ft<kotlin/String, kotlin/String?>!>, test/WildcardBounds.A<in ft<kotlin/String, kotlin/String?>!>?>!|): R|kotlin/Unit|
public constructor(): R|test/WildcardBounds| public constructor(): R|test/WildcardBounds|
@@ -1,7 +1,7 @@
public open class MethodWithMappedClasses : R|kotlin/Any| { public open class MethodWithMappedClasses : R|kotlin/Any| {
public open operator fun <T> copy(dest: R|ft<kotlin/collections/MutableList<in T>, kotlin/collections/List<in T>?>!|, src: R|ft<kotlin/collections/MutableList<ft<T, T?>!>, kotlin/collections/List<ft<T, T?>!>?>!|): R|kotlin/Unit| public open operator fun <T> copy(dest: R|ft<kotlin/collections/MutableList<in ft<T, T?>!>, kotlin/collections/List<in ft<T, T?>!>?>!|, src: R|ft<kotlin/collections/MutableList<ft<T, T?>!>, kotlin/collections/List<ft<T, T?>!>?>!|): R|kotlin/Unit|
public open operator fun <T> copyMap(dest: R|ft<kotlin/collections/MutableMap<ft<kotlin/String, kotlin/String?>!, in T>, kotlin/collections/Map<ft<kotlin/String, kotlin/String?>!, in T>?>!|, src: R|ft<kotlin/collections/MutableMap<ft<kotlin/String, kotlin/String?>!, ft<T, T?>!>, kotlin/collections/Map<ft<kotlin/String, kotlin/String?>!, ft<T, T?>!>?>!|): R|kotlin/Unit| public open operator fun <T> copyMap(dest: R|ft<kotlin/collections/MutableMap<ft<kotlin/String, kotlin/String?>!, in ft<T, T?>!>, kotlin/collections/Map<ft<kotlin/String, kotlin/String?>!, in ft<T, T?>!>?>!|, src: R|ft<kotlin/collections/MutableMap<ft<kotlin/String, kotlin/String?>!, ft<T, T?>!>, kotlin/collections/Map<ft<kotlin/String, kotlin/String?>!, ft<T, T?>!>?>!|): R|kotlin/Unit|
public constructor(): R|test/MethodWithMappedClasses| public constructor(): R|test/MethodWithMappedClasses|
@@ -1,5 +1,5 @@
public open class MethodWithTypeParameters : R|kotlin/Any| { public open class MethodWithTypeParameters : R|kotlin/Any| {
public open operator fun <A, B : R|ft<java/lang/Runnable, java/lang/Runnable?>!|, R|ft<kotlin/collections/MutableList<kotlin/Cloneable>, kotlin/collections/MutableList<kotlin/Cloneable>?>!|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out B>, kotlin/collections/List<out B>?>!|, list: R|ft<kotlin/collections/MutableList<in kotlin/String>, kotlin/collections/List<in kotlin/String>?>!|): R|kotlin/Unit| public open operator fun <A, B : R|ft<java/lang/Runnable, java/lang/Runnable?>!|, R|ft<kotlin/collections/MutableList<ft<kotlin/Cloneable, kotlin/Cloneable?>!>, kotlin/collections/List<ft<kotlin/Cloneable, kotlin/Cloneable?>!>?>!|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out ft<B, B?>!>, kotlin/collections/List<out ft<B, B?>!>?>!|, list: R|ft<kotlin/collections/MutableList<in ft<kotlin/String, kotlin/String?>!>, kotlin/collections/List<in ft<kotlin/String, kotlin/String?>!>?>!|): R|kotlin/Unit|
public constructor(): R|test/MethodWithTypeParameters| public constructor(): R|test/MethodWithTypeParameters|
@@ -1,5 +1,5 @@
public open class PropertyArrayTypes<T> : R|kotlin/Any| { public open class PropertyArrayTypes<T> : R|kotlin/Any| {
public open field arrayOfArrays: R|ft<kotlin/Array<ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<ft<kotlin/String, kotlin/String?>!>?>!>, kotlin/Array<out ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<ft<kotlin/String, kotlin/String?>!>?>!>?>!| public open field arrayOfArrays: R|ft<kotlin/Array<ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<out ft<kotlin/String, kotlin/String?>!>?>!>, kotlin/Array<out ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<out ft<kotlin/String, kotlin/String?>!>?>!>?>!|
public open field array: R|ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<out ft<kotlin/String, kotlin/String?>!>?>!| public open field array: R|ft<kotlin/Array<ft<kotlin/String, kotlin/String?>!>, kotlin/Array<out ft<kotlin/String, kotlin/String?>!>?>!|
@@ -1,5 +1,5 @@
public open class WrongTypeParameterBoundStructure1 : R|kotlin/Any| { public open class WrongTypeParameterBoundStructure1 : R|kotlin/Any| {
public open operator fun <A, B : R|ft<java/lang/Runnable, java/lang/Runnable?>!|, R|ft<kotlin/collections/MutableList<kotlin/Cloneable>, kotlin/collections/MutableList<kotlin/Cloneable>?>!|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out B>, kotlin/collections/List<out B>?>!|): R|kotlin/Unit| public open operator fun <A, B : R|ft<java/lang/Runnable, java/lang/Runnable?>!|, R|ft<kotlin/collections/MutableList<ft<kotlin/Cloneable, kotlin/Cloneable?>!>, kotlin/collections/List<ft<kotlin/Cloneable, kotlin/Cloneable?>!>?>!|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out ft<B, B?>!>, kotlin/collections/List<out ft<B, B?>!>?>!|): R|kotlin/Unit|
public constructor(): R|test/WrongTypeParameterBoundStructure1| public constructor(): R|test/WrongTypeParameterBoundStructure1|
@@ -1,5 +1,5 @@
public open class Max : R|kotlin/Any| { public open class Max : R|kotlin/Any| {
public open operator fun <T : R|ft<kotlin/Any, kotlin/Any?>!|, R|ft<kotlin/Comparable<in T>, kotlin/Comparable<in T>?>!|> max(coll: R|ft<kotlin/collections/MutableCollection<out T>, kotlin/collections/Collection<out T>?>!|): R|ft<T, T?>!| public open operator fun <T : R|ft<kotlin/Any, kotlin/Any?>!|, R|ft<kotlin/Comparable<in ft<T, T?>!>, kotlin/Comparable<in ft<T, T?>!>?>!|> max(coll: R|ft<kotlin/collections/MutableCollection<out ft<T, T?>!>, kotlin/collections/Collection<out ft<T, T?>!>?>!|): R|ft<T, T?>!|
public constructor(): R|test/Max| public constructor(): R|test/Max|
@@ -1,6 +1,6 @@
public abstract interface ReadOnlyExtendsWildcard : R|kotlin/Any| { public abstract interface ReadOnlyExtendsWildcard : R|kotlin/Any| {
public abstract operator fun bar(): R|kotlin/Unit| public abstract operator fun bar(): R|kotlin/Unit|
public abstract operator fun foo(@R|kotlin/annotations/jvm/ReadOnly|() x: R|ft<kotlin/collections/List<out kotlin/CharSequence>, kotlin/collections/List<out kotlin/CharSequence>?>!|, @R|org/jetbrains/annotations/NotNull|() y: R|kotlin/Comparable<in kotlin/String>|): R|kotlin/Unit| public abstract operator fun foo(@R|kotlin/annotations/jvm/ReadOnly|() x: R|ft<kotlin/collections/List<out ft<kotlin/CharSequence, kotlin/CharSequence?>!>, kotlin/collections/List<out ft<kotlin/CharSequence, kotlin/CharSequence?>!>?>!|, @R|org/jetbrains/annotations/NotNull|() y: R|kotlin/Comparable<in ft<kotlin/String, kotlin/String?>!>|): R|kotlin/Unit|
} }
@@ -1,5 +1,5 @@
public open class NotNullIntArray : R|kotlin/Any| { public open class NotNullIntArray : R|kotlin/Any| {
@R|org/jetbrains/annotations/NotNull|() public open operator fun hi(): R|ft<kotlin/IntArray, kotlin/IntArray?>!| @R|org/jetbrains/annotations/NotNull|() public open operator fun hi(): R|kotlin/IntArray|
public constructor(): R|test/NotNullIntArray| public constructor(): R|test/NotNullIntArray|
@@ -1,5 +1,5 @@
public open class NotNullObjectArray : R|kotlin/Any| { public open class NotNullObjectArray : R|kotlin/Any| {
@R|org/jetbrains/annotations/NotNull|() public open operator fun hi(): R|ft<kotlin/Array<ft<kotlin/Any, kotlin/Any?>!>, kotlin/Array<out ft<kotlin/Any, kotlin/Any?>!>?>!| @R|org/jetbrains/annotations/NotNull|() public open operator fun hi(): R|ft<kotlin/Array<ft<kotlin/Any, kotlin/Any?>!>, kotlin/Array<out ft<kotlin/Any, kotlin/Any?>!>>|
public constructor(): R|test/NotNullObjectArray| public constructor(): R|test/NotNullObjectArray|
@@ -1,4 +1,4 @@
public abstract interface GenericInterfaceParameterWithSelfBound<T : R|ft<test/GenericInterfaceParameterWithSelfBound<T>, test/GenericInterfaceParameterWithSelfBound<T>?>!|> : R|kotlin/Any| { public abstract interface GenericInterfaceParameterWithSelfBound<T : R|ft<test/GenericInterfaceParameterWithSelfBound<ft<T, T?>!>, test/GenericInterfaceParameterWithSelfBound<ft<T, T?>!>?>!|> : R|kotlin/Any| {
public abstract operator fun method(t: R|ft<T, T?>!|): R|ft<T, T?>!| public abstract operator fun method(t: R|ft<T, T?>!|): R|ft<T, T?>!|
} }
@@ -1,4 +1,4 @@
public abstract interface GenericInterfaceParametersWithBounds<A : R|ft<kotlin/Comparable<A>, kotlin/Comparable<A>?>!|, R|ft<kotlin/Cloneable, kotlin/Cloneable?>!|, B : R|ft<kotlin/collections/MutableList<A>, kotlin/collections/MutableList<A>?>!|> : R|kotlin/Any| { public abstract interface GenericInterfaceParametersWithBounds<A : R|ft<kotlin/Comparable<ft<A, A?>!>, kotlin/Comparable<ft<A, A?>!>?>!|, R|ft<kotlin/Cloneable, kotlin/Cloneable?>!|, B : R|ft<kotlin/collections/MutableList<ft<A, A?>!>, kotlin/collections/List<ft<A, A?>!>?>!|> : R|kotlin/Any| {
public abstract operator fun method(a: R|ft<kotlin/Array<ft<A, A?>!>, kotlin/Array<out ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit| public abstract operator fun method(a: R|ft<kotlin/Array<ft<A, A?>!>, kotlin/Array<out ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
} }
@@ -1,4 +1,4 @@
public abstract interface GenericMethodParameters : R|kotlin/Any| { public abstract interface GenericMethodParameters : R|kotlin/Any| {
public abstract operator fun <A : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|, B : R|ft<kotlin/collections/MutableList<A>, kotlin/collections/MutableList<A>?>!|> method(a: R|ft<kotlin/Array<ft<A, A?>!>, kotlin/Array<out ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit| public abstract operator fun <A : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|, B : R|ft<kotlin/collections/MutableList<ft<A, A?>!>, kotlin/collections/List<ft<A, A?>!>?>!|> method(a: R|ft<kotlin/Array<ft<A, A?>!>, kotlin/Array<out ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
} }
@@ -5,7 +5,7 @@ public open class NonTrivialFunctionType : R|kotlin/Any| {
public open operator fun wildcardUnbound(comparator: R|ft<java/util/Comparator<*>, java/util/Comparator<*>?>!|): R|kotlin/Unit| public open operator fun wildcardUnbound(comparator: R|ft<java/util/Comparator<*>, java/util/Comparator<*>?>!|): R|kotlin/Unit|
public open operator fun wildcardBound(comparator: R|ft<java/util/Comparator<in kotlin/CharSequence>, java/util/Comparator<in kotlin/CharSequence>?>!|): R|kotlin/Unit| public open operator fun wildcardBound(comparator: R|ft<java/util/Comparator<in ft<kotlin/CharSequence, kotlin/CharSequence?>!>, java/util/Comparator<in ft<kotlin/CharSequence, kotlin/CharSequence?>!>?>!|): R|kotlin/Unit|
public constructor(): R|test/NonTrivialFunctionType| public constructor(): R|test/NonTrivialFunctionType|
@@ -3,7 +3,7 @@ public open class TypeParameterOfMethod : R|kotlin/Any| {
public open static operator fun <T : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|> max2(comparator: R|ft<java/util/Comparator<ft<T, T?>!>, java/util/Comparator<ft<T, T?>!>?>!|, value1: R|ft<T, T?>!|, value2: R|ft<T, T?>!|): R|ft<T, T?>!| public open static operator fun <T : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|> max2(comparator: R|ft<java/util/Comparator<ft<T, T?>!>, java/util/Comparator<ft<T, T?>!>?>!|, value1: R|ft<T, T?>!|, value2: R|ft<T, T?>!|): R|ft<T, T?>!|
public open static operator fun <A : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|, B : R|ft<kotlin/collections/MutableList<A>, kotlin/collections/MutableList<A>?>!|> method(a: R|ft<java/util/Comparator<ft<A, A?>!>, java/util/Comparator<ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit| public open static operator fun <A : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|, B : R|ft<kotlin/collections/MutableList<ft<A, A?>!>, kotlin/collections/List<ft<A, A?>!>?>!|> method(a: R|ft<java/util/Comparator<ft<A, A?>!>, java/util/Comparator<ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
public constructor(): R|test/TypeParameterOfMethod| public constructor(): R|test/TypeParameterOfMethod|