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:
@@ -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")
|
||||
}
|
||||
|
||||
+10
-7
@@ -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|))
|
||||
}
|
||||
)
|
||||
|
||||
+31
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+31
@@ -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)
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -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
@@ -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
|
||||
|
||||
Vendored
+32
-32
@@ -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
|
||||
|
||||
+34
-34
@@ -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>|
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -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>|
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -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|
|
||||
|
||||
|
||||
+2
-2
@@ -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
-1
@@ -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
-1
@@ -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
-1
@@ -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
-1
@@ -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
-1
@@ -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
-1
@@ -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
-1
@@ -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|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -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|
|
||||
|
||||
|
||||
+1
-1
@@ -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|
|
||||
|
||||
|
||||
Reference in New Issue
Block a user