diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index 8409d1bacaa..0c0cbebd9f1 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -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().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 { diff --git a/compiler/testData/loadJava/compiledJava/RemoveRedundantProjectionKind.fir.txt b/compiler/testData/loadJava/compiledJava/RemoveRedundantProjectionKind.fir.txt index 31f8152dea3..a6d7f9f83df 100644 --- a/compiler/testData/loadJava/compiledJava/RemoveRedundantProjectionKind.fir.txt +++ b/compiler/testData/loadJava/compiledJava/RemoveRedundantProjectionKind.fir.txt @@ -1,6 +1,6 @@ public abstract interface RemoveRedundantProjectionKind : R|java/lang/Object| { - public abstract operator function f(collection: R|ft, java/util/Collection?>|!): R|kotlin/Unit| + public abstract operator function f(collection: R|ft, java/util/Collection?>|!): R|kotlin/Unit| - public abstract operator function f(comparator: R|ft, java/lang/Comparable?>|!): R|kotlin/Unit| + public abstract operator function f(comparator: R|ft, java/lang/Comparable?>|!): R|kotlin/Unit| } diff --git a/compiler/testData/loadJava/compiledJava/UnboundWildcard.fir.txt b/compiler/testData/loadJava/compiledJava/UnboundWildcard.fir.txt index b0e56b2d2ea..69393aae35f 100644 --- a/compiler/testData/loadJava/compiledJava/UnboundWildcard.fir.txt +++ b/compiler/testData/loadJava/compiledJava/UnboundWildcard.fir.txt @@ -1,6 +1,6 @@ public final class UnboundWildcard : R|java/lang/Object| { - public final operator function foo(): R|ft, test/UnboundWildcard.MyClass?>|! + public final operator function foo(): R|ft, test/UnboundWildcard.MyClass<*>?>|! - public final operator function collection(): R|ft, java/util/Collection?>|! + public final operator function collection(): R|ft, java/util/Collection<*>?>|! } diff --git a/compiler/testData/loadJava/compiledJava/WildcardBounds.fir.txt b/compiler/testData/loadJava/compiledJava/WildcardBounds.fir.txt index 48a06b31bdc..53034b36d9d 100644 --- a/compiler/testData/loadJava/compiledJava/WildcardBounds.fir.txt +++ b/compiler/testData/loadJava/compiledJava/WildcardBounds.fir.txt @@ -1,4 +1,4 @@ public open class WildcardBounds : R|java/lang/Object| { - public/*package*/ open operator function foo(x: R|ft, test/WildcardBounds.A?>|!, y: R|ft, test/WildcardBounds.A?>|!): R|kotlin/Unit| + public/*package*/ open operator function foo(x: R|ft, test/WildcardBounds.A?>|!, y: R|ft, test/WildcardBounds.A?>|!): R|kotlin/Unit| } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.fir.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.fir.txt index 53ff599c332..81d2afa8f2b 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.fir.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.fir.txt @@ -1,5 +1,5 @@ public open class MethodWithMappedClasses : R|java/lang/Object| { - public open operator function copy(dest: R|ft, java/util/List?>|!, src: R|ft>, kotlin/collections/List>>|): R|kotlin/Unit| + public open operator function copy(dest: R|ft, java/util/List?>|!, src: R|ft>, kotlin/collections/List>>|): R|kotlin/Unit| public open operator function copyMap(dest: R|ft, *>, kotlin/collections/Map, *>>|, src: R|ft, ft>, kotlin/collections/Map, ft>>|): R|kotlin/Unit| diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt index 1832433168e..d780aff5edf 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt @@ -1,4 +1,4 @@ public open class MethodWithTypeParameters : R|java/lang/Object| { - public open operator function foo(a: R|ft|!, b: R|ft, java/util/List?>|!, list: R|ft, java/util/List?>|!): R|kotlin/Unit| + public open operator function foo(a: R|ft|!, b: R|ft, java/util/List?>|!, list: R|ft, java/util/List?>|!): R|kotlin/Unit| } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/StarProjection.fir.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/StarProjection.fir.txt index 1ae3ba3be8e..e509784fc88 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/StarProjection.fir.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/StarProjection.fir.txt @@ -1,4 +1,4 @@ public final class StarProjection : R|java/lang/Object| { - public final operator function foo(): R|ft, test/StarProjection.MyClass?>|! + public final operator function foo(): R|ft, test/StarProjection.MyClass<*>?>|! } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt index f2d3c10ff9a..640c291be18 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt @@ -1,4 +1,4 @@ public open class WrongTypeParameterBoundStructure1 : R|java/lang/Object| { - public open operator function foo(a: R|ft|!, b: R|ft, java/util/List?>|!): R|kotlin/Unit| + public open operator function foo(a: R|ft|!, b: R|ft, java/util/List?>|!): R|kotlin/Unit| } diff --git a/compiler/testData/loadJava/compiledJava/library/Max.fir.txt b/compiler/testData/loadJava/compiledJava/library/Max.fir.txt index 3b981ffd9bf..dbda758a0e3 100644 --- a/compiler/testData/loadJava/compiledJava/library/Max.fir.txt +++ b/compiler/testData/loadJava/compiledJava/library/Max.fir.txt @@ -1,4 +1,4 @@ public open class Max : R|java/lang/Object| { - public open operator function max(coll: R|ft, java/util/Collection?>|!): R|ft|! + public open operator function max(coll: R|ft, java/util/Collection?>|!): R|ft|! } diff --git a/compiler/testData/loadJava/compiledJava/mutability/ReadOnlyExtendsWildcard.fir.txt b/compiler/testData/loadJava/compiledJava/mutability/ReadOnlyExtendsWildcard.fir.txt index b16ae8e4016..3cd5442ff22 100644 --- a/compiler/testData/loadJava/compiledJava/mutability/ReadOnlyExtendsWildcard.fir.txt +++ b/compiler/testData/loadJava/compiledJava/mutability/ReadOnlyExtendsWildcard.fir.txt @@ -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, java/util/List?>|!, @R|org/jetbrains/annotations/NotNull|() y: R|ft, kotlin/Comparable<*>>|): R|kotlin/Unit| + public abstract operator function foo(@R|kotlin/annotations/jvm/ReadOnly|() x: R|ft, java/util/List?>|!, @R|org/jetbrains/annotations/NotNull|() y: R|ft, kotlin/Comparable<*>>|): R|kotlin/Unit| } diff --git a/compiler/testData/loadJava/compiledJava/sam/adapters/NonTrivialFunctionType.fir.txt b/compiler/testData/loadJava/compiledJava/sam/adapters/NonTrivialFunctionType.fir.txt index 1de1eb9cac8..395846ba1e9 100644 --- a/compiler/testData/loadJava/compiledJava/sam/adapters/NonTrivialFunctionType.fir.txt +++ b/compiler/testData/loadJava/compiledJava/sam/adapters/NonTrivialFunctionType.fir.txt @@ -3,8 +3,8 @@ public open class NonTrivialFunctionType : R|java/lang/Object| { public open operator function foo(comparator: R|ft>, java/util/Comparator>>|): R|kotlin/Unit| - public open operator function wildcardUnbound(comparator: R|ft, java/util/Comparator?>|!): R|kotlin/Unit| + public open operator function wildcardUnbound(comparator: R|ft, java/util/Comparator<*>?>|!): R|kotlin/Unit| - public open operator function wildcardBound(comparator: R|ft, java/util/Comparator?>|!): R|kotlin/Unit| + public open operator function wildcardBound(comparator: R|ft, java/util/Comparator?>|!): R|kotlin/Unit| }