Skip to content

Commit efc534a

Browse files
committed
Add implied wildcards when extracting type parameter bounds
kotlinc seems to always insert wildcards where type parameter variance implies them, and ignores @JvmSuppressWildcards at least in 1.6.20.
1 parent c1592cb commit efc534a

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import org.jetbrains.kotlin.ir.expressions.*
1919
import org.jetbrains.kotlin.ir.symbols.*
2020
import org.jetbrains.kotlin.ir.types.*
2121
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
2225
import org.jetbrains.kotlin.name.FqName
2326
import org.jetbrains.kotlin.types.Variance
2427
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -172,7 +175,7 @@ open class KotlinFileExtractor(
172175
}
173176
}
174177

175-
fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int): Label<out DbTypevariable>? {
178+
fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label<out DbTypevariable>? {
176179
with("type parameter", tp) {
177180
val parentId = getTypeParameterParentLabel(tp) ?: return null
178181
val id = tw.getLabelFor<DbTypevariable>(getTypeParameterLabel(tp))
@@ -184,10 +187,21 @@ open class KotlinFileExtractor(
184187
val locId = tw.getLocation(tp)
185188
tw.writeHasLocation(id, locId)
186189

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+
187198
tp.superTypes.forEachIndexed { boundIdx, bound ->
188199
if(!(bound.isAny() || bound.isNullableAny())) {
189200
tw.getLabelFor<DbTypebound>("@\"bound;$boundIdx;{$id}\"") {
190-
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)
191205
}
192206
}
193207
}
@@ -383,7 +397,9 @@ open class KotlinFileExtractor(
383397

384398
extractEnclosingClass(c, id, locId, listOf())
385399

386-
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)) }
387403
if (extractDeclarations) {
388404
c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
389405
if (extractStaticInitializer)
@@ -675,7 +691,8 @@ open class KotlinFileExtractor(
675691
with("function", f) {
676692
DeclarationStackAdjuster(f).use {
677693

678-
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)) }
679696

680697
val id =
681698
idOverride
@@ -709,7 +726,7 @@ open class KotlinFileExtractor(
709726

710727
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature!! }
711728

712-
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, getJavaMethod(f)?.returnType)
729+
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, javaMethod?.returnType)
713730
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext.RETURN, pluginContext) } ?: adjustedReturnType
714731

715732
val locId = locOverride ?: getLocation(f, classTypeArgsIncludingOuterClasses)

0 commit comments

Comments
 (0)