Generate function type parameter annotations and type annotations on their bounds into bytecode

Generate type parameter annotation by default for `-Xjvm-target 1.8` and above

 #KT-46539
 #KT-13228
 #KT-46545 Fixed
This commit is contained in:
Mikhael Bogdanov
2021-05-04 09:41:26 +02:00
committed by TeamCityServer
parent 209ec68591
commit cbe3c66156
23 changed files with 691 additions and 2 deletions
@@ -53,6 +53,8 @@ fun IrType.isTypeParameter() = classifierOrNull is IrTypeParameterSymbol
fun IrType.isInterface() = classOrNull?.owner?.kind == ClassKind.INTERFACE
fun IrType.isAnnotation() = classOrNull?.owner?.kind == ClassKind.ANNOTATION_CLASS
fun IrType.isFunctionOrKFunction() = isFunction() || isKFunction()
fun IrType.isSuspendFunctionOrKFunction() = isSuspendFunction() || isKSuspendFunction()
@@ -336,7 +336,7 @@ abstract class AnnotationCodegen(
val IrConstructorCall.annotationClass get() = symbol.owner.parentAsClass
}
private fun generateTypeAnnotations(
internal fun generateTypeAnnotations(
annotated: IrAnnotationContainer,
type: IrType?
) {
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.codegen.inline.wrapWithMaxLocalCalc
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
@@ -37,6 +39,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.TypeReference.METHOD_TYPE_PARAMETER_BOUND
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.MethodNode
@@ -46,6 +49,7 @@ class FunctionCodegen(
private val inlinedInto: ExpressionCodegen? = null
) {
private val context = classCodegen.context
val emitTypeAnnotations = context.state.configuration.getBoolean(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS)
fun generate(): SMAPAndMethodNode =
try {
@@ -89,6 +93,54 @@ class FunctionCodegen(
)
}
}.genAnnotations(irFunction, signature.asmMethod.returnType, irFunction.returnType)
if (context.state.target != JvmTarget.JVM_1_6) {
irFunction.typeParameters.forEachIndexed { index, typeParameter ->
object : AnnotationCodegen(classCodegen, context, true) {
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
return methodVisitor.visitTypeAnnotation(
TypeReference.newTypeParameterReference(TypeReference.METHOD_TYPE_PARAMETER, index).value,
null,
descr,
visible
)
}
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
throw RuntimeException(
"Error during generation: type annotation shouldn't be presented on type parameter: " +
"${ir2string(typeParameter)} in ${ir2string(irFunction)}"
)
}
}.genAnnotations(typeParameter, null, null)
if (emitTypeAnnotations) {
var superInterfaceIndex = 1
typeParameter.superTypes.forEach { superType ->
val isClassOrTypeParameter = !superType.isInterface() && !superType.isAnnotation()
val superIndex = if (isClassOrTypeParameter) 0 else superInterfaceIndex++
object : AnnotationCodegen(classCodegen, context, true) {
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
throw RuntimeException(
"Error during generation: only type annotations should be presented on type parameters bounds: " +
"${ir2string(typeParameter)} in ${ir2string(typeParameter)}"
)
}
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
return methodVisitor.visitTypeAnnotation(
TypeReference.newTypeParameterBoundReference(METHOD_TYPE_PARAMETER_BOUND, index, superIndex).value,
path,
descr,
visible
)
}
}.generateTypeAnnotations(irFunction, superType)
}
}
}
}
if (shouldGenerateAnnotationsOnValueParameters()) {
generateParameterAnnotations(irFunction, methodVisitor, signature, classCodegen, context, skipNullabilityAnnotations)
}