FIR Java types: handle wildcard types correctly
Related to KT-29937, KT-29218
This commit is contained in:
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.java
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirTypeParameterImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTagImpl
|
||||
@@ -31,7 +33,7 @@ import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.Variance.*
|
||||
|
||||
internal val JavaModifierListOwner.modality: Modality
|
||||
get() = when {
|
||||
@@ -123,7 +125,13 @@ internal fun JavaType.toConeKotlinTypeWithNullability(session: FirSession, isNul
|
||||
internal fun JavaClassifierType.toConeKotlinTypeWithNullability(session: FirSession, isNullable: Boolean): ConeLookupTagBasedType {
|
||||
return when (val classifier = classifier) {
|
||||
is JavaClass -> {
|
||||
classifier.classId!!.toConeKotlinType(typeArguments.map { it.toConeProjection(session) }.toTypedArray(), isNullable)
|
||||
val classId = classifier.classId!!
|
||||
val symbol = session.service<FirSymbolProvider>().getClassLikeSymbolByFqName(classId) as? FirClassSymbol
|
||||
symbol?.constructType(
|
||||
typeArguments.mapIndexed { index, argument ->
|
||||
argument.toConeProjection(session, symbol.fir.typeParameters.getOrNull(index))
|
||||
}.toTypedArray(), isNullable
|
||||
) ?: ConeClassErrorType("Symbol not found, for `$classId`")
|
||||
}
|
||||
is JavaTypeParameter -> {
|
||||
// TODO: it's unclear how to identify type parameter by the symbol
|
||||
@@ -137,7 +145,7 @@ internal fun JavaClassifierType.toConeKotlinTypeWithNullability(session: FirSess
|
||||
|
||||
internal fun createTypeParameterSymbol(session: FirSession, name: Name): FirTypeParameterSymbol {
|
||||
val firSymbol = FirTypeParameterSymbol()
|
||||
FirTypeParameterImpl(session, null, firSymbol, name, variance = Variance.INVARIANT, isReified = false)
|
||||
FirTypeParameterImpl(session, null, firSymbol, name, variance = INVARIANT, isReified = false)
|
||||
return firSymbol
|
||||
}
|
||||
|
||||
@@ -164,11 +172,26 @@ internal fun FirAbstractAnnotatedElement.addAnnotationsFrom(javaAnnotationOwner:
|
||||
}
|
||||
}
|
||||
|
||||
private fun JavaType.toConeProjection(session: FirSession): ConeKotlinTypeProjection {
|
||||
if (this is JavaClassifierType) {
|
||||
return toConeKotlinTypeWithNullability(session, isNullable = false)
|
||||
private fun JavaType.toConeProjection(session: FirSession, boundTypeParameter: FirTypeParameter?): ConeKotlinTypeProjection {
|
||||
return when (this) {
|
||||
is JavaWildcardType -> {
|
||||
val bound = this.bound
|
||||
val argumentVariance = if (isExtends) OUT_VARIANCE else IN_VARIANCE
|
||||
val parameterVariance = boundTypeParameter?.variance ?: INVARIANT
|
||||
if (bound == null || parameterVariance != INVARIANT && parameterVariance != argumentVariance) {
|
||||
ConeStarProjection
|
||||
} else {
|
||||
val boundType = bound.toConeKotlinTypeWithNullability(session, isNullable = false)
|
||||
if (argumentVariance == OUT_VARIANCE) {
|
||||
ConeKotlinTypeProjectionOut(boundType)
|
||||
} else {
|
||||
ConeKotlinTypeProjectionIn(boundType)
|
||||
}
|
||||
}
|
||||
}
|
||||
is JavaClassifierType -> toConeKotlinTypeWithNullability(session, isNullable = false)
|
||||
else -> ConeClassErrorType("Unexpected type argument: $this")
|
||||
}
|
||||
return ConeClassErrorType("Unexpected type argument: $this")
|
||||
}
|
||||
|
||||
private fun JavaAnnotationArgument.toFirExpression(session: FirSession): FirExpression {
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
public abstract interface RemoveRedundantProjectionKind : R|java/lang/Object| {
|
||||
public abstract operator function f(collection: R|ft<java/util/Collection<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends CharSequence>, java/util/Collection<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends CharSequence>?>|!): R|kotlin/Unit|
|
||||
public abstract operator function f(collection: R|ft<java/util/Collection<out java/lang/CharSequence>, java/util/Collection<out java/lang/CharSequence>?>|!): R|kotlin/Unit|
|
||||
|
||||
public abstract operator function f(comparator: R|ft<java/lang/Comparable<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super CharSequence>, java/lang/Comparable<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super CharSequence>?>|!): R|kotlin/Unit|
|
||||
public abstract operator function f(comparator: R|ft<java/lang/Comparable<in java/lang/CharSequence>, java/lang/Comparable<in java/lang/CharSequence>?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
public final class UnboundWildcard : R|java/lang/Object| {
|
||||
public final operator function foo(): R|ft<test/UnboundWildcard.MyClass<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>, test/UnboundWildcard.MyClass<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>?>|!
|
||||
public final operator function foo(): R|ft<test/UnboundWildcard.MyClass<*>, test/UnboundWildcard.MyClass<*>?>|!
|
||||
|
||||
public final operator function collection(): R|ft<java/util/Collection<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>, java/util/Collection<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>?>|!
|
||||
public final operator function collection(): R|ft<java/util/Collection<*>, java/util/Collection<*>?>|!
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public open class WildcardBounds : R|java/lang/Object| {
|
||||
public/*package*/ open operator function foo(x: R|ft<test/WildcardBounds.A<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends CharSequence>, test/WildcardBounds.A<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends CharSequence>?>|!, y: R|ft<test/WildcardBounds.A<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super String>, test/WildcardBounds.A<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super String>?>|!): R|kotlin/Unit|
|
||||
public/*package*/ open operator function foo(x: R|ft<test/WildcardBounds.A<out java/lang/CharSequence>, test/WildcardBounds.A<out java/lang/CharSequence>?>|!, y: R|ft<test/WildcardBounds.A<in java/lang/String>, test/WildcardBounds.A<in java/lang/String>?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
public open class MethodWithMappedClasses : R|java/lang/Object| {
|
||||
public open operator function copy(dest: R|ft<java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super T>, java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super T>?>|!, src: R|ft<kotlin/collections/MutableList<ft<T, T?>>, kotlin/collections/List<ft<T, T?>>>|): R|kotlin/Unit|
|
||||
public open operator function copy(dest: R|ft<java/util/List<in T>, java/util/List<in T>?>|!, src: R|ft<kotlin/collections/MutableList<ft<T, T?>>, kotlin/collections/List<ft<T, T?>>>|): R|kotlin/Unit|
|
||||
|
||||
public open operator function copyMap(dest: R|ft<kotlin/collections/MutableMap<ft<java/lang/String, java/lang/String?>, *>, kotlin/collections/Map<ft<java/lang/String, java/lang/String?>, *>>|, src: R|ft<kotlin/collections/MutableMap<ft<java/lang/String, java/lang/String?>, ft<T, T?>>, kotlin/collections/Map<ft<java/lang/String, java/lang/String?>, ft<T, T?>>>|): R|kotlin/Unit|
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public open class MethodWithTypeParameters : R|java/lang/Object| {
|
||||
public open operator function foo(a: R|ft<A, A?>|!, b: R|ft<java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends B>, java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends B>?>|!, list: R|ft<java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super String>, java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super String>?>|!): R|kotlin/Unit|
|
||||
public open operator function foo(a: R|ft<A, A?>|!, b: R|ft<java/util/List<out B>, java/util/List<out B>?>|!, list: R|ft<java/util/List<in java/lang/String>, java/util/List<in java/lang/String>?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public final class StarProjection : R|java/lang/Object| {
|
||||
public final operator function foo(): R|ft<test/StarProjection.MyClass<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>, test/StarProjection.MyClass<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>?>|!
|
||||
public final operator function foo(): R|ft<test/StarProjection.MyClass<*>, test/StarProjection.MyClass<*>?>|!
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public open class WrongTypeParameterBoundStructure1 : R|java/lang/Object| {
|
||||
public open operator function foo(a: R|ft<A, A?>|!, b: R|ft<java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends B>, java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends B>?>|!): R|kotlin/Unit|
|
||||
public open operator function foo(a: R|ft<A, A?>|!, b: R|ft<java/util/List<out B>, java/util/List<out B>?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public open class Max : R|java/lang/Object| {
|
||||
public open operator function max(coll: R|ft<java/util/Collection<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends T>, java/util/Collection<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends T>?>|!): R|ft<T, T?>|!
|
||||
public open operator function max(coll: R|ft<java/util/Collection<out T>, java/util/Collection<out T>?>|!): R|ft<T, T?>|!
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
public abstract interface ReadOnlyExtendsWildcard : R|java/lang/Object| {
|
||||
public abstract operator function bar(): R|kotlin/Unit|
|
||||
|
||||
public abstract operator function foo(@R|kotlin/annotations/jvm/ReadOnly|() x: R|ft<kotlin/collections/List<*>, java/util/List<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? extends CharSequence>?>|!, @R|org/jetbrains/annotations/NotNull|() y: R|ft<kotlin/Comparable<*>, kotlin/Comparable<*>>|): R|kotlin/Unit|
|
||||
public abstract operator function foo(@R|kotlin/annotations/jvm/ReadOnly|() x: R|ft<kotlin/collections/List<*>, java/util/List<out java/lang/CharSequence>?>|!, @R|org/jetbrains/annotations/NotNull|() y: R|ft<kotlin/Comparable<*>, kotlin/Comparable<*>>|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ public open class NonTrivialFunctionType : R|java/lang/Object| {
|
||||
|
||||
public open operator function foo(comparator: R|ft<java/util/Comparator<ft<java/lang/String, java/lang/String?>>, java/util/Comparator<ft<java/lang/String, java/lang/String?>>>|): R|kotlin/Unit|
|
||||
|
||||
public open operator function wildcardUnbound(comparator: R|ft<java/util/Comparator<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>, java/util/Comparator<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:?>?>|!): R|kotlin/Unit|
|
||||
public open operator function wildcardUnbound(comparator: R|ft<java/util/Comparator<*>, java/util/Comparator<*>?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function wildcardBound(comparator: R|ft<java/util/Comparator<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super CharSequence>, java/util/Comparator<class error: Unexpected type argument: JavaWildcardTypeImpl: PsiType:? super CharSequence>?>|!): R|kotlin/Unit|
|
||||
public open operator function wildcardBound(comparator: R|ft<java/util/Comparator<in java/lang/CharSequence>, java/util/Comparator<in java/lang/CharSequence>?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user