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,
) {
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()
}
@@ -260,7 +265,7 @@ class JavaSymbolProvider(
firJavaClass.replaceSuperTypeRefs(
javaClass.supertypes.map { supertype ->
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.builder.FirAnnotationContainerBuilder
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.FirValueParameter
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.references.builder.buildErrorNamedReference
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.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.impl.ConeClassLikeLookupTagImpl
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.load.java.structure.*
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.Name
import org.jetbrains.kotlin.types.Variance.*
@@ -65,24 +70,17 @@ internal fun ClassId.toConeKotlinType(
return ConeClassLikeTypeImpl(lookupTag, typeArguments, isNullable)
}
internal fun FirTypeRef.toNotNullConeKotlinType(
internal fun FirTypeRef.toConeKotlinTypeProbablyFlexible(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): ConeKotlinType =
when (this) {
is FirResolvedTypeRef -> type
is FirJavaTypeRef -> {
val javaType = type
javaType.toNotNullConeKotlinType(session, javaTypeParameterStack)
type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
}
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 {
val annotations = (this as? JavaClassifierType)?.annotations.orEmpty()
return buildJavaTypeRef {
@@ -94,25 +92,29 @@ internal fun JavaType.toFirJavaTypeRef(session: FirSession, javaTypeParameterSta
internal fun JavaClassifierType.toFirResolvedTypeRef(
session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
nullability: ConeNullability = ConeNullability.NOT_NULL,
typeParametersNullability: ConeNullability = ConeNullability.NOT_NULL
isForSupertypes: Boolean,
forTypeParameterBounds: Boolean
): 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 {
type = coneType
this@toFirResolvedTypeRef.annotations.mapTo(annotations) { it.toFirAnnotationCall(session, javaTypeParameterStack) }
}
}
internal fun JavaType?.toConeKotlinTypeWithNullability(
internal fun JavaType?.toConeKotlinTypeWithoutEnhancement(
session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
nullability: ConeNullability,
typeParametersNullability: ConeNullability = ConeNullability.NOT_NULL
javaTypeParameterStack: JavaTypeParameterStack
): ConeKotlinType {
return when (this) {
is JavaClassifierType -> {
toConeKotlinTypeWithNullability(session, nullability, typeParametersNullability, javaTypeParameterStack)
toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
}
is JavaPrimitiveType -> {
val primitiveType = type
@@ -120,77 +122,204 @@ internal fun JavaType?.toConeKotlinTypeWithNullability(
null -> "Unit"
else -> javaName.capitalize()
}
val classId = StandardClassIds.byName(kotlinPrimitiveName)
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
classId.toConeKotlinType(emptyArray(), isNullable = false)
}
is JavaArrayType -> {
val componentType = componentType
if (componentType !is JavaPrimitiveType) {
val classId = StandardClassIds.Array
val argumentType = ConeFlexibleType(
componentType.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NOT_NULL),
componentType.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, ConeNullability.NULLABLE)
val argumentType = componentType.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
classId.toConeFlexibleType(
arrayOf(argumentType),
typeArgumentsForUpper = arrayOf(ConeKotlinTypeProjectionOut(argumentType))
)
classId.toConeKotlinType(arrayOf(argumentType), nullability.isNullable)
} else {
val javaComponentName = componentType.type?.typeName?.asString()?.capitalize() ?: error("Array of voids")
val classId = StandardClassIds.byName(javaComponentName + "Array")
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
classId.toConeFlexibleType(emptyArray())
}
}
is JavaWildcardType -> bound?.toNotNullConeKotlinType(session, javaTypeParameterStack) ?: run {
val classId = StandardClassIds.Any
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
is JavaWildcardType -> bound?.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) ?: run {
StandardClassIds.Any.toConeFlexibleType(emptyArray())
}
null -> {
val classId = StandardClassIds.Any
classId.toConeKotlinType(emptyArray(), nullability.isNullable)
StandardClassIds.Any.toConeFlexibleType(emptyArray())
}
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,
nullability: ConeNullability,
typeParametersNullability: ConeNullability,
javaTypeParameterStack: JavaTypeParameterStack
javaTypeParameterStack: JavaTypeParameterStack,
forTypeParameterBounds: Boolean = false
): ConeKotlinType {
if (nullability == ConeNullability.UNKNOWN) {
return ConeFlexibleType(
toConeKotlinTypeWithNullability(session, ConeNullability.NOT_NULL, typeParametersNullability, javaTypeParameterStack),
toConeKotlinTypeWithNullability(session, ConeNullability.NULLABLE, typeParametersNullability, javaTypeParameterStack)
)
val lowerBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds)
val upperBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = false, forTypeParameterBounds)
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) {
is JavaClass -> {
//val classId = 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 mappedTypeArguments = when (isRaw) {
true -> classifier.typeParameters.map { ConeStarProjection }
false -> typeArguments.map { argument ->
argument.toConeProjection(
session, javaTypeParameterStack, boundTypeParameter = null, nullability = typeParametersNullability
val mappedTypeArguments = if (isRaw) {
val defaultArgs = (1..classifier.typeParameters.size).map { ConeStarProjection }
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(
mappedTypeArguments.toTypedArray(), nullability.isNullable
mappedTypeArguments.toTypedArray(), isNullable = !isLowerBound
)
}
is JavaTypeParameter -> {
val symbol = javaTypeParameterStack[classifier]
ConeTypeParameterTypeImpl(symbol.toLookupTag(), nullability.isNullable)
ConeTypeParameterTypeImpl(symbol.toLookupTag(), isNullable = !isLowerBound)
}
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(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): FirAnnotationCall {
@@ -226,11 +355,10 @@ internal fun JavaValueParameter.toFirValueParameter(
}
}
internal fun JavaType?.toConeProjection(
private fun JavaType?.toConeProjectionWithoutEnhancement(
session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
boundTypeParameter: FirTypeParameter?,
nullability: ConeNullability = ConeNullability.NOT_NULL
boundTypeParameter: FirTypeParameter?
): ConeKotlinTypeProjection {
return when (this) {
null -> ConeStarProjection
@@ -241,7 +369,7 @@ internal fun JavaType?.toConeProjection(
if (bound == null || parameterVariance != INVARIANT && parameterVariance != argumentVariance) {
ConeStarProjection
} else {
val boundType = bound.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability)
val boundType = bound.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
if (argumentVariance == OUT_VARIANCE) {
ConeKotlinTypeProjectionOut(boundType)
} 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")
}
}
@@ -342,7 +470,12 @@ internal fun Any?.createConstant(session: FirSession): FirExpression {
private fun JavaType.toFirResolvedTypeRef(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
): FirResolvedTypeRef {
if (this is JavaClassifierType) return toFirResolvedTypeRef(session, javaTypeParameterStack)
if (this is JavaClassifierType) return toFirResolvedTypeRef(
session,
javaTypeParameterStack,
isForSupertypes = false,
forTypeParameterBounds = false
)
return buildResolvedTypeRef {
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.classId
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.toNotNullConeKotlinType
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.types.*
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
else {
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(
enhancedCurrent, wereChanges = true, containsFunctionN = containsFunctionN
)
@@ -150,10 +153,10 @@ internal class EnhancementSignatureParts(
}
}
is FirJavaTypeRef -> {
val convertedType = type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack)
Pair(
// TODO: optimize
type.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability = ConeNullability.NOT_NULL),
type.toConeKotlinTypeWithNullability(session, javaTypeParameterStack, nullability = ConeNullability.NULLABLE)
convertedType.lowerBoundIfFlexible(),
convertedType.upperBoundIfFlexible()
)
}
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.declarations.FirJavaClass
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.resolve.*
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
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.FirCallableSymbol
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.NullDefaultValue
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.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
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.extractRadix
@@ -56,60 +53,23 @@ internal class IndexedJavaTypeQualifiers(private val data: Array<JavaTypeQualifi
internal fun FirJavaTypeRef.enhance(
session: FirSession,
javaTypeParameterStack: JavaTypeParameterStack,
qualifiers: IndexedJavaTypeQualifiers
qualifiers: IndexedJavaTypeQualifiers,
typeWithoutEnhancement: ConeKotlinType,
): 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:
// 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.
// 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,
javaTypeParameterStack: JavaTypeParameterStack,
annotations: List<FirAnnotationCall>,
qualifiers: IndexedJavaTypeQualifiers,
index: Int
): FirResolvedTypeRef {
val type = this
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)
}
}
val enhanced = enhanceConeKotlinType(session, qualifiers, index)
return buildResolvedTypeRef {
this.type = enhanced
@@ -117,9 +77,34 @@ private fun JavaType?.enhancePossiblyFlexible(
}
}
private fun JavaType?.subtreeSize(): Int {
if (this !is JavaClassifierType) return 1
return 1 + typeArguments.sumBy { it?.subtreeSize() ?: 0 }
private fun ConeKotlinType.enhanceConeKotlinType(
session: FirSession,
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(
@@ -164,155 +149,43 @@ private fun ClassId.mutableToReadOnly(): ClassId? {
}
}
// 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}]")
}
fun computeProjection(
private fun ConeKotlinType.enhanceInflexibleType(
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,
qualifiers: IndexedJavaTypeQualifiers,
index: Int
): ConeKotlinType {
val originalTag = when (val classifier = classifier) {
is JavaClass -> {
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)
require(this !is ConeFlexibleType) {
"$this should not be flexible"
}
if (this !is ConeLookupTagBasedType) return this
val originalTag = lookupTag
val effectiveQualifiers = qualifiers(index)
val enhancedTag = originalTag.enhanceMutability(effectiveQualifiers, position)
val enhancedArguments = if (isRaw) {
val firClassifier = originalTag.toSymbol(session)!!.firUnsafe<FirRegularClass>()
firClassifier.typeParameters.map {
val fir = it
val erasedUpperBound = fir.getErasedUpperBound {
firClassifier.defaultType().withArguments(firClassifier.typeParameters.map { ConeStarProjection }.toTypedArray())
}
computeProjection(session, fir, position, erasedUpperBound)
}
val enhancedArguments = if (this is RawType) {
// TODO: Support enhancing for raw types
typeArguments
} else {
var globalArgIndex = index + 1
arguments.mapIndexed { localArgIndex, arg ->
if (arg is JavaWildcardType) {
typeArguments.mapIndexed { localArgIndex, arg ->
if (arg.kind != ProjectionKind.INVARIANT) {
globalArgIndex++
arg.toConeProjection(
session,
javaTypeParameterStack,
((originalTag as? FirBasedSymbol<*>)?.fir as? FirCallableMemberDeclaration<*>)?.typeParameters?.getOrNull(localArgIndex)
)
arg
} else {
val argEnhancedTypeRef =
arg.enhancePossiblyFlexible(session, javaTypeParameterStack, annotations, qualifiers, globalArgIndex)
require(arg is ConeKotlinType) { "Should be invariant type: $arg" }
globalArgIndex += arg.subtreeSize()
argEnhancedTypeRef.type.type.toTypeProjection(Variance.INVARIANT)
arg.enhanceConeKotlinType(session, qualifiers, globalArgIndex)
}
}
}.toTypedArray()
}
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
// 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.java.JavaTypeParameterStack
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.scopes.impl.FirAbstractOverrideChecker
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 }
}
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
)
if (boundType != null) {
@@ -49,8 +49,8 @@ class JavaOverrideChecker internal constructor(
override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) =
isEqualTypes(
candidateTypeRef.toNotNullConeKotlinType(session, javaTypeParameterStack),
baseTypeRef.toNotNullConeKotlinType(session, javaTypeParameterStack),
candidateTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
baseTypeRef.toConeKotlinTypeProbablyFlexible(session, javaTypeParameterStack),
substitutor
)
@@ -189,10 +189,10 @@ fun ConeClassLikeLookupTag.constructClassType(
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) {
is ConeTypeParameterLookupTag -> ConeTypeParameterTypeImpl(this, isNullable)
is ConeClassLikeLookupTag -> this.constructClassType(typeArguments, isNullable)
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 get(): R|DiagnosticFactory0<DerivedElement>|
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|
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>>| {
when () {
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|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
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>| {
lval setOfValues: R|kotlin/collections/MutableSet<D>| = when (lval <elvis>: R|kotlin/collections/MutableSet<D>| = R|<local>/maybeValues|) {
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|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>!| = R|<local>/maybeValues|) {
==($subj$, Null(null)) -> {
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| {
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 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|<local>/key|.R|kotlin/String.length|
^ R|<local>/value|.R|kotlin/String.length|
@@ -1,4 +1,4 @@
FILE: capturedFlexible.kt
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
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 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|>()
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|))
}
)
@@ -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() {
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
platformNN[0]
platformN[0]
<!INAPPLICABLE_CANDIDATE!>platformN[0]<!>
platformJ[0]
platformNN[0] = 1
platformN[0] = 1
<!INAPPLICABLE_CANDIDATE!>platformN[0] = 1<!>
platformJ[0] = 1
}
@@ -21,11 +21,11 @@ fun test() {
val platformJ = J.staticJ
platformNN[0]
platformN[0]
<!INAPPLICABLE_CANDIDATE!>platformN[0]<!>
platformJ[0]
platformNN[0] = 1
platformN[0] = 1
<!INAPPLICABLE_CANDIDATE!>platformN[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
BRANCH
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
<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
<class: K>: K1 of <root>.plus
<class: V>: V1 of <root>.plus
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?>
$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: 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
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
$receiver: VALUE_PARAMETER name:<this> type:java.util.LinkedHashMap<K1 of <root>.plus, V1 of <root>.plus>
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
$receiver: VALUE_PARAMETER name:<this> type:java.util.LinkedHashMap<K1 of <root>.plus?, V1 of <root>.plus?>
BLOCK_BODY
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
$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
$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
@@ -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
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
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
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
VAR name:x type:kotlin.String [val]
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
VAR name:y type:kotlin.String [val]
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
VAR name:y type:kotlin.String? [val]
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
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
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
BLOCK_BODY
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
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
VAR name:x type:kotlin.String [val]
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
VAR name:y type:kotlin.String [val]
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
VAR name:y type:kotlin.String? [val]
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
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
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
BLOCK_BODY
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
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
VAR name:x type:kotlin.String [val]
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
VAR name:y type:kotlin.String [val]
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
VAR name:y type:kotlin.String? [val]
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
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
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
BLOCK_BODY
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
<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
<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
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
<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
<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
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
$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]
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
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
$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
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
BLOCK_BODY
BLOCK type=kotlin.Unit origin=FOR_LOOP
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
$this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null
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
$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
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
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
$this: GET_VAR 'val tmp_0: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListUnused' type=kotlin.collections.MutableIterator<<root>.P> origin=null
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
$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
BLOCK_BODY
BLOCK type=kotlin.Unit origin=FOR_LOOP
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
$this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null
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
$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
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
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
$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 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
$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]
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]
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
BLOCK_BODY
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
$this: 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: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
$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
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
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
$this: GET_VAR 'val iterator: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testDesugaredForInList' type=kotlin.collections.MutableIterator<<root>.P> origin=null
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
$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
VALUE_PARAMETER name:j index:0 type:<root>.J
BLOCK_BODY
BLOCK type=kotlin.Unit origin=FOR_LOOP
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
$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
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
@@ -64,27 +64,27 @@ FILE fqName:<root> fileName:/enhancedNullabilityInForLoop.kt
FUN name:testForInListUse visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
BLOCK type=kotlin.Unit origin=FOR_LOOP
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
$this: CALL 'public open fun listOfNotNull (): kotlin.collections.List<<root>.P>? [operator] declared in <root>.J' type=kotlin.collections.List<<root>.P>? origin=null
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
$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
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
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
$this: GET_VAR 'val tmp_3: kotlin.collections.MutableIterator<<root>.P> [val] declared in <root>.testForInListUse' type=kotlin.collections.MutableIterator<<root>.P> origin=null
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
$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
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
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
VALUE_PARAMETER name:j index:0 type:<root>.J
BLOCK_BODY
BLOCK type=kotlin.Unit origin=FOR_LOOP
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
$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
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
@@ -1,4 +1,4 @@
public open class ClassWithTypePRefNext<R : R|ft<kotlin/collections/MutableIterable<P>, kotlin/collections/MutableIterable<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 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<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 constructor<P : R|ft<kotlin/Enum<P>, kotlin/Enum<P>?>!|>(): R|test/ClassWithTypePRefSelf<P>|
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<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 constructor<P : R|ft<test/ClassWithTypePRefSelfAndClass<P>, test/ClassWithTypePRefSelfAndClass<P>?>!|>(): R|test/ClassWithTypePRefSelfAndClass<P>|
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<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 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/*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|
@@ -1,7 +1,7 @@
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|
@@ -1,5 +1,5 @@
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|
@@ -1,5 +1,5 @@
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?>!>?>!|
@@ -1,5 +1,5 @@
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|
@@ -1,5 +1,5 @@
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|
@@ -1,6 +1,6 @@
public abstract interface ReadOnlyExtendsWildcard : R|kotlin/Any| {
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| {
@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|
@@ -1,5 +1,5 @@
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|
@@ -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?>!|
}
@@ -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|
}
@@ -1,4 +1,4 @@
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 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|
@@ -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 <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|