Kotlin: annotation properties should be java.lang.Class not KClass

As documented at https://kotlinlang.org/docs/annotations.html#constructors, annotation properties of type KClass get rewritten when targeting the JVM.
This commit is contained in:
Chris Smowton
2022-07-14 18:24:23 +01:00
parent a8197b27aa
commit f774467892
7 changed files with 192 additions and 7 deletions

View File

@@ -1103,7 +1103,50 @@ open class KotlinUsesExtractor(
return "@\"$prefix;{$parentId}.$name($paramTypeIds){$returnTypeId}${typeArgSuffix}\""
}
val javaLangClass by lazy {
val result = pluginContext.referenceClass(FqName("java.lang.Class"))?.owner
result?.let { extractExternalClassLater(it) }
result
}
fun kClassToJavaClass(t: IrType): IrType {
when(t) {
is IrSimpleType -> {
if (t.classifier == pluginContext.irBuiltIns.kClassClass) {
javaLangClass?.let { jlc ->
return jlc.symbol.typeWithArguments(t.arguments)
}
} else if (t.isArray() || t.isNullableArray()) {
val elementType = t.getArrayElementType(pluginContext.irBuiltIns)
val replacedElementType = kClassToJavaClass(elementType)
if (replacedElementType !== elementType) {
val newArg = makeTypeProjection(replacedElementType, (t.arguments[0] as IrTypeProjection).variance)
return t.classOrNull!!.typeWithArguments(listOf(newArg)).codeQlWithHasQuestionMark(t.isNullableArray())
}
}
}
}
return t
}
fun isAnnotationClassField(f: IrField) =
f.correspondingPropertySymbol?.let {
isAnnotationClassProperty(it)
} ?: false
fun isAnnotationClassProperty(p: IrPropertySymbol) =
p.owner.parentClassOrNull?.kind == ClassKind.ANNOTATION_CLASS
fun getAdjustedReturnType(f: IrFunction) : IrType {
// Replace annotation val accessor types as needed:
(f as? IrSimpleFunction)?.correspondingPropertySymbol?.let {
if (isAnnotationClassProperty(it) && f == it.owner.getter) {
val replaced = kClassToJavaClass(f.returnType)
if (replaced != f.returnType)
return replaced
}
}
// The return type of `java.util.concurrent.ConcurrentHashMap<K,V>.keySet/0` is defined as `Set<K>` in the stubs inside the Android SDK.
// This does not match the Java SDK return type: `ConcurrentHashMap.KeySetView<K,V>`, so it's adjusted here.
// This is a deliberate change in the Android SDK: https://github.com/AndroidSDKSources/android-sdk-sources-for-api-level-31/blob/2c56b25f619575bea12f9c5520ed2259620084ac/java/util/concurrent/ConcurrentHashMap.java#L1244-L1249