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.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
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.declarations.impl.FirTypeParameterImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
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.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
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.service
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTagImpl
|
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.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance.*
|
||||||
|
|
||||||
internal val JavaModifierListOwner.modality: Modality
|
internal val JavaModifierListOwner.modality: Modality
|
||||||
get() = when {
|
get() = when {
|
||||||
@@ -123,7 +125,13 @@ internal fun JavaType.toConeKotlinTypeWithNullability(session: FirSession, isNul
|
|||||||
internal fun JavaClassifierType.toConeKotlinTypeWithNullability(session: FirSession, isNullable: Boolean): ConeLookupTagBasedType {
|
internal fun JavaClassifierType.toConeKotlinTypeWithNullability(session: FirSession, isNullable: Boolean): ConeLookupTagBasedType {
|
||||||
return when (val classifier = classifier) {
|
return when (val classifier = classifier) {
|
||||||
is JavaClass -> {
|
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 -> {
|
is JavaTypeParameter -> {
|
||||||
// TODO: it's unclear how to identify type parameter by the symbol
|
// 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 {
|
internal fun createTypeParameterSymbol(session: FirSession, name: Name): FirTypeParameterSymbol {
|
||||||
val firSymbol = 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
|
return firSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,11 +172,26 @@ internal fun FirAbstractAnnotatedElement.addAnnotationsFrom(javaAnnotationOwner:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JavaType.toConeProjection(session: FirSession): ConeKotlinTypeProjection {
|
private fun JavaType.toConeProjection(session: FirSession, boundTypeParameter: FirTypeParameter?): ConeKotlinTypeProjection {
|
||||||
if (this is JavaClassifierType) {
|
return when (this) {
|
||||||
return toConeKotlinTypeWithNullability(session, isNullable = false)
|
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 {
|
private fun JavaAnnotationArgument.toFirExpression(session: FirSession): FirExpression {
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
public abstract interface RemoveRedundantProjectionKind : R|java/lang/Object| {
|
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 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 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 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|
|
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 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 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 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 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 interface ReadOnlyExtendsWildcard : R|java/lang/Object| {
|
||||||
public abstract operator function bar(): R|kotlin/Unit|
|
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 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