@@ -19,7 +19,11 @@ import org.jetbrains.kotlin.ir.expressions.*
19
19
import org.jetbrains.kotlin.ir.symbols.*
20
20
import org.jetbrains.kotlin.ir.types.*
21
21
import 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
22
25
import org.jetbrains.kotlin.name.FqName
26
+ import org.jetbrains.kotlin.types.Variance
23
27
import org.jetbrains.kotlin.util.OperatorNameConventions
24
28
import java.io.Closeable
25
29
import java.util.*
@@ -171,7 +175,7 @@ open class KotlinFileExtractor(
171
175
}
172
176
}
173
177
174
- fun extractTypeParameter (tp : IrTypeParameter , apparentIndex : Int ): Label <out DbTypevariable >? {
178
+ fun extractTypeParameter (tp : IrTypeParameter , apparentIndex : Int , javaTypeParameter : JavaTypeParameter ? ): Label <out DbTypevariable >? {
175
179
with (" type parameter" , tp) {
176
180
val parentId = getTypeParameterParentLabel(tp) ? : return null
177
181
val id = tw.getLabelFor<DbTypevariable >(getTypeParameterLabel(tp))
@@ -183,10 +187,21 @@ open class KotlinFileExtractor(
183
187
val locId = tw.getLocation(tp)
184
188
tw.writeHasLocation(id, locId)
185
189
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
+
186
198
tp.superTypes.forEachIndexed { boundIdx, bound ->
187
199
if (! (bound.isAny() || bound.isNullableAny())) {
188
200
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)
190
205
}
191
206
}
192
207
}
@@ -382,7 +397,9 @@ open class KotlinFileExtractor(
382
397
383
398
extractEnclosingClass(c, id, locId, listOf ())
384
399
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)) }
386
403
if (extractDeclarations) {
387
404
c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
388
405
if (extractStaticInitializer)
@@ -497,7 +514,9 @@ open class KotlinFileExtractor(
497
514
else
498
515
null
499
516
} ? : 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
501
520
val id = useValueParameter(vp, parent)
502
521
if (extractTypeAccess) {
503
522
extractTypeAccessRecursive(substitutedType, location, id, - 1 )
@@ -531,7 +550,9 @@ open class KotlinFileExtractor(
531
550
extensionReceiverParameter = null ,
532
551
functionTypeParameters = listOf (),
533
552
classTypeArgsIncludingOuterClasses = listOf (),
534
- overridesCollectionsMethod = false
553
+ overridesCollectionsMethod = false ,
554
+ javaSignature = null ,
555
+ addParameterWildcardsByDefault = false
535
556
)
536
557
val clinitId = tw.getLabelFor<DbMethod >(clinitLabel)
537
558
val returnType = useType(pluginContext.irBuiltIns.unitType, TypeContext .RETURN )
@@ -670,7 +691,8 @@ open class KotlinFileExtractor(
670
691
with (" function" , f) {
671
692
DeclarationStackAdjuster (f).use {
672
693
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)) }
674
696
675
697
val id =
676
698
idOverride
@@ -704,7 +726,7 @@ open class KotlinFileExtractor(
704
726
705
727
val paramsSignature = allParamTypes.joinToString(separator = " ," , prefix = " (" , postfix = " )" ) { it.javaResult.signature!! }
706
728
707
- val adjustedReturnType = getAdjustedReturnType(f)
729
+ val adjustedReturnType = addJavaLoweringWildcards( getAdjustedReturnType(f), false , javaMethod?.returnType )
708
730
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext .RETURN , pluginContext) } ? : adjustedReturnType
709
731
710
732
val locId = locOverride ? : getLocation(f, classTypeArgsIncludingOuterClasses)
@@ -3744,6 +3766,17 @@ open class KotlinFileExtractor(
3744
3766
}
3745
3767
}
3746
3768
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
+
3747
3780
/* *
3748
3781
* Extracts a single type access expression with no enclosing callable and statement.
3749
3782
*/
@@ -3768,15 +3801,36 @@ open class KotlinFileExtractor(
3768
3801
return id
3769
3802
}
3770
3803
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
+
3771
3825
/* *
3772
3826
* Extracts a type access expression and its child type access expressions in case of a generic type. Nested generics are also handled.
3773
3827
* No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations.
3774
3828
*/
3775
3829
private fun extractTypeAccessRecursive (t : IrType , location : Label <DbLocation >, parent : Label <out DbExprparent >, idx : Int , typeContext : TypeContext = TypeContext .OTHER ): Label <out DbExpr > {
3776
3830
val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx)
3777
3831
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)
3780
3834
}
3781
3835
}
3782
3836
return typeAccessId
0 commit comments