@@ -19,7 +19,11 @@ import org.jetbrains.kotlin.ir.expressions.*
1919import org.jetbrains.kotlin.ir.symbols.*
2020import org.jetbrains.kotlin.ir.types.*
2121import org.jetbrains.kotlin.ir.util.*
22+ import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
23+ import org.jetbrains.kotlin.load.java.structure.JavaClass
24+ import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
2225import org.jetbrains.kotlin.name.FqName
26+ import org.jetbrains.kotlin.types.Variance
2327import org.jetbrains.kotlin.util.OperatorNameConventions
2428import java.io.Closeable
2529import java.util.*
@@ -171,7 +175,7 @@ open class KotlinFileExtractor(
171175 }
172176 }
173177
174- fun extractTypeParameter (tp : IrTypeParameter , apparentIndex : Int ): Label <out DbTypevariable >? {
178+ fun extractTypeParameter (tp : IrTypeParameter , apparentIndex : Int , javaTypeParameter : JavaTypeParameter ? ): Label <out DbTypevariable >? {
175179 with (" type parameter" , tp) {
176180 val parentId = getTypeParameterParentLabel(tp) ? : return null
177181 val id = tw.getLabelFor<DbTypevariable >(getTypeParameterLabel(tp))
@@ -183,10 +187,21 @@ open class KotlinFileExtractor(
183187 val locId = tw.getLocation(tp)
184188 tw.writeHasLocation(id, locId)
185189
190+ // Annoyingly, we have no obvious way to pair up the bounds of an IrTypeParameter and a JavaTypeParameter
191+ // because JavaTypeParameter provides a Collection not an ordered list, so we can only do our best here:
192+ fun tryGetJavaBound (idx : Int ) =
193+ when (tp.superTypes.size) {
194+ 1 -> javaTypeParameter?.upperBounds?.singleOrNull()
195+ else -> (javaTypeParameter?.upperBounds as ? List )?.getOrNull(idx)
196+ }
197+
186198 tp.superTypes.forEachIndexed { boundIdx, bound ->
187199 if (! (bound.isAny() || bound.isNullableAny())) {
188200 tw.getLabelFor<DbTypebound >(" @\" bound;$boundIdx ;{$id }\" " ) {
189- tw.writeTypeBounds(it, useType(bound).javaResult.id.cast<DbReftype >(), boundIdx, id)
201+ // Note we don't look for @JvmSuppressWildcards here because it doesn't seem to have any impact
202+ // on kotlinc adding wildcards to type parameter bounds.
203+ val boundWithWildcards = addJavaLoweringWildcards(bound, true , tryGetJavaBound(tp.index))
204+ tw.writeTypeBounds(it, useType(boundWithWildcards).javaResult.id.cast<DbReftype >(), boundIdx, id)
190205 }
191206 }
192207 }
@@ -382,7 +397,9 @@ open class KotlinFileExtractor(
382397
383398 extractEnclosingClass(c, id, locId, listOf ())
384399
385- c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx) }
400+ val javaClass = (c.source as ? JavaSourceElement )?.javaElement as ? JavaClass
401+
402+ c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx, javaClass?.typeParameters?.getOrNull(idx)) }
386403 if (extractDeclarations) {
387404 c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
388405 if (extractStaticInitializer)
@@ -497,7 +514,9 @@ open class KotlinFileExtractor(
497514 else
498515 null
499516 } ? : vp.type
500- val substitutedType = typeSubstitution?.let { it(maybeErasedType, TypeContext .OTHER , pluginContext) } ? : maybeErasedType
517+ val javaType = ((vp.parent as ? IrFunction )?.let { getJavaMethod(it) })?.valueParameters?.getOrNull(idx)?.type
518+ val typeWithWildcards = addJavaLoweringWildcards(maybeErasedType, ! hasWildcardSuppressionAnnotation(vp), javaType)
519+ val substitutedType = typeSubstitution?.let { it(typeWithWildcards, TypeContext .OTHER , pluginContext) } ? : typeWithWildcards
501520 val id = useValueParameter(vp, parent)
502521 if (extractTypeAccess) {
503522 extractTypeAccessRecursive(substitutedType, location, id, - 1 )
@@ -531,7 +550,9 @@ open class KotlinFileExtractor(
531550 extensionReceiverParameter = null ,
532551 functionTypeParameters = listOf (),
533552 classTypeArgsIncludingOuterClasses = listOf (),
534- overridesCollectionsMethod = false
553+ overridesCollectionsMethod = false ,
554+ javaSignature = null ,
555+ addParameterWildcardsByDefault = false
535556 )
536557 val clinitId = tw.getLabelFor<DbMethod >(clinitLabel)
537558 val returnType = useType(pluginContext.irBuiltIns.unitType, TypeContext .RETURN )
@@ -670,7 +691,8 @@ open class KotlinFileExtractor(
670691 with (" function" , f) {
671692 DeclarationStackAdjuster (f).use {
672693
673- getFunctionTypeParameters(f).mapIndexed { idx, tp -> extractTypeParameter(tp, idx) }
694+ val javaMethod = getJavaMethod(f)
695+ getFunctionTypeParameters(f).mapIndexed { idx, tp -> extractTypeParameter(tp, idx, javaMethod?.typeParameters?.getOrNull(idx)) }
674696
675697 val id =
676698 idOverride
@@ -704,7 +726,7 @@ open class KotlinFileExtractor(
704726
705727 val paramsSignature = allParamTypes.joinToString(separator = " ," , prefix = " (" , postfix = " )" ) { it.javaResult.signature!! }
706728
707- val adjustedReturnType = getAdjustedReturnType(f)
729+ val adjustedReturnType = addJavaLoweringWildcards( getAdjustedReturnType(f), false , javaMethod?.returnType )
708730 val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext .RETURN , pluginContext) } ? : adjustedReturnType
709731
710732 val locId = locOverride ? : getLocation(f, classTypeArgsIncludingOuterClasses)
@@ -3744,6 +3766,17 @@ open class KotlinFileExtractor(
37443766 }
37453767 }
37463768
3769+ /* *
3770+ * Extracts a single wildcard type access expression with no enclosing callable and statement.
3771+ */
3772+ private fun extractWildcardTypeAccess (type : TypeResults , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int ): Label <out DbExpr > {
3773+ val id = tw.getFreshIdLabel<DbWildcardtypeaccess >()
3774+ tw.writeExprs_wildcardtypeaccess(id, type.javaResult.id, parent, idx)
3775+ tw.writeExprsKotlinType(id, type.kotlinResult.id)
3776+ tw.writeHasLocation(id, location)
3777+ return id
3778+ }
3779+
37473780 /* *
37483781 * Extracts a single type access expression with no enclosing callable and statement.
37493782 */
@@ -3768,15 +3801,36 @@ open class KotlinFileExtractor(
37683801 return id
37693802 }
37703803
3804+ /* *
3805+ * Extracts a type argument type access, introducing a wildcard type access if appropriate, or directly calling
3806+ * `extractTypeAccessRecursive` if the argument is invariant.
3807+ * No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations.
3808+ */
3809+ private fun extractWildcardTypeAccessRecursive (t : IrTypeArgument , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int ) {
3810+ val typeLabels by lazy { TypeResults (getTypeArgumentLabel(t), TypeResult (fakeKotlinType(), " TODO" , " TODO" )) }
3811+ when (t) {
3812+ is IrStarProjection -> extractWildcardTypeAccess(typeLabels, location, parent, idx)
3813+ is IrTypeProjection -> when (t.variance) {
3814+ Variance .INVARIANT -> extractTypeAccessRecursive(t.type, location, parent, idx, TypeContext .GENERIC_ARGUMENT )
3815+ else -> {
3816+ val wildcardLabel = extractWildcardTypeAccess(typeLabels, location, parent, idx)
3817+ // Mimic a Java extractor oddity, that it uses the child index to indicate what kind of wildcard this is
3818+ val boundChildIdx = if (t.variance == Variance .OUT_VARIANCE ) 0 else 1
3819+ extractTypeAccessRecursive(t.type, location, wildcardLabel, boundChildIdx, TypeContext .GENERIC_ARGUMENT )
3820+ }
3821+ }
3822+ }
3823+ }
3824+
37713825 /* *
37723826 * Extracts a type access expression and its child type access expressions in case of a generic type. Nested generics are also handled.
37733827 * No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations.
37743828 */
37753829 private fun extractTypeAccessRecursive (t : IrType , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int , typeContext : TypeContext = TypeContext .OTHER ): Label <out DbExpr > {
37763830 val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx)
37773831 if (t is IrSimpleType ) {
3778- t.arguments.filterIsInstance< IrType >(). forEachIndexed { argIdx, arg ->
3779- extractTypeAccessRecursive (arg, location, typeAccessId, argIdx, TypeContext . GENERIC_ARGUMENT )
3832+ t.arguments.forEachIndexed { argIdx, arg ->
3833+ extractWildcardTypeAccessRecursive (arg, location, typeAccessId, argIdx)
37803834 }
37813835 }
37823836 return typeAccessId
0 commit comments