Extract generation of type parameters annotations and annotation on their bounds into utils
This commit is contained in:
committed by
TeamCityServer
parent
cbe3c66156
commit
40eeee48b6
+61
-5
@@ -43,9 +43,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
|
||||||
import org.jetbrains.org.objectweb.asm.TypePath
|
|
||||||
import java.lang.annotation.RetentionPolicy
|
import java.lang.annotation.RetentionPolicy
|
||||||
|
|
||||||
abstract class AnnotationCodegen(
|
abstract class AnnotationCodegen(
|
||||||
@@ -107,10 +105,10 @@ abstract class AnnotationCodegen(
|
|||||||
generateTypeAnnotations(annotated, typeForTypeAnnotations)
|
generateTypeAnnotations(annotated, typeForTypeAnnotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor
|
abstract fun visitAnnotation(descr: String, visible: Boolean): AnnotationVisitor
|
||||||
|
|
||||||
open fun visitTypeAnnotation(
|
open fun visitTypeAnnotation(
|
||||||
descr: String?,
|
descr: String,
|
||||||
path: TypePath?,
|
path: TypePath?,
|
||||||
visible: Boolean,
|
visible: Boolean,
|
||||||
): AnnotationVisitor {
|
): AnnotationVisitor {
|
||||||
@@ -287,6 +285,64 @@ abstract class AnnotationCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
fun genAnnotationsOnTypeParametersAndBounds(
|
||||||
|
context: JvmBackendContext,
|
||||||
|
typeParameterContainer: IrTypeParametersContainer,
|
||||||
|
classCodegen: ClassCodegen,
|
||||||
|
referenceType: Int,
|
||||||
|
boundType: Int,
|
||||||
|
visitor: (typeRef: Int, typePath: TypePath?, descriptor: String, visible: Boolean) -> AnnotationVisitor
|
||||||
|
) {
|
||||||
|
if (context.state.target != JVM_1_6) {
|
||||||
|
typeParameterContainer.typeParameters.forEachIndexed { index, typeParameter ->
|
||||||
|
object : AnnotationCodegen(classCodegen, context, true) {
|
||||||
|
override fun visitAnnotation(descr: String, visible: Boolean): AnnotationVisitor {
|
||||||
|
|
||||||
|
return visitor(
|
||||||
|
TypeReference.newTypeParameterReference(referenceType, 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(typeParameterContainer)}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.genAnnotations(typeParameter, null, null)
|
||||||
|
|
||||||
|
if (context.state.configuration.getBoolean(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS)) {
|
||||||
|
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 visitor(
|
||||||
|
TypeReference.newTypeParameterBoundReference(boundType, index, superIndex).value,
|
||||||
|
path,
|
||||||
|
descr,
|
||||||
|
visible
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.generateTypeAnnotations(typeParameterContainer, superType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isInvisibleForNullabilityAnalysis(declaration: IrDeclaration): Boolean =
|
private fun isInvisibleForNullabilityAnalysis(declaration: IrDeclaration): Boolean =
|
||||||
when {
|
when {
|
||||||
declaration.origin.isSynthetic ->
|
declaration.origin.isSynthetic ->
|
||||||
|
|||||||
+13
-54
@@ -20,8 +20,6 @@ import org.jetbrains.kotlin.codegen.inline.wrapWithMaxLocalCalc
|
|||||||
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
|
import org.jetbrains.kotlin.codegen.mangleNameIfNeeded
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.visitAnnotableParameterCount
|
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.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -39,7 +37,6 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
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.commons.InstructionAdapter
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
|
||||||
@@ -49,7 +46,6 @@ class FunctionCodegen(
|
|||||||
private val inlinedInto: ExpressionCodegen? = null
|
private val inlinedInto: ExpressionCodegen? = null
|
||||||
) {
|
) {
|
||||||
private val context = classCodegen.context
|
private val context = classCodegen.context
|
||||||
val emitTypeAnnotations = context.state.configuration.getBoolean(JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS)
|
|
||||||
|
|
||||||
fun generate(): SMAPAndMethodNode =
|
fun generate(): SMAPAndMethodNode =
|
||||||
try {
|
try {
|
||||||
@@ -83,62 +79,25 @@ class FunctionCodegen(
|
|||||||
if (irFunction.origin !in methodOriginsWithoutAnnotations) {
|
if (irFunction.origin !in methodOriginsWithoutAnnotations) {
|
||||||
val skipNullabilityAnnotations = flags and Opcodes.ACC_PRIVATE != 0 || flags and Opcodes.ACC_SYNTHETIC != 0
|
val skipNullabilityAnnotations = flags and Opcodes.ACC_PRIVATE != 0 || flags and Opcodes.ACC_SYNTHETIC != 0
|
||||||
object : AnnotationCodegen(classCodegen, context, skipNullabilityAnnotations) {
|
object : AnnotationCodegen(classCodegen, context, skipNullabilityAnnotations) {
|
||||||
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
override fun visitAnnotation(descr: String, visible: Boolean): AnnotationVisitor {
|
||||||
return methodVisitor.visitAnnotation(descr, visible)
|
return methodVisitor.visitAnnotation(descr, visible)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
override fun visitTypeAnnotation(descr: String, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
||||||
return methodVisitor.visitTypeAnnotation(
|
return methodVisitor.visitTypeAnnotation(
|
||||||
TypeReference.newTypeReference(TypeReference.METHOD_RETURN).value, path, descr, visible
|
TypeReference.newTypeReference(TypeReference.METHOD_RETURN).value, path, descr, visible
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.genAnnotations(irFunction, signature.asmMethod.returnType, irFunction.returnType)
|
}.genAnnotations(irFunction, signature.asmMethod.returnType, irFunction.returnType)
|
||||||
|
|
||||||
if (context.state.target != JvmTarget.JVM_1_6) {
|
AnnotationCodegen.genAnnotationsOnTypeParametersAndBounds(
|
||||||
irFunction.typeParameters.forEachIndexed { index, typeParameter ->
|
context,
|
||||||
object : AnnotationCodegen(classCodegen, context, true) {
|
irFunction,
|
||||||
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
classCodegen,
|
||||||
return methodVisitor.visitTypeAnnotation(
|
TypeReference.METHOD_TYPE_PARAMETER,
|
||||||
TypeReference.newTypeParameterReference(TypeReference.METHOD_TYPE_PARAMETER, index).value,
|
TypeReference.METHOD_TYPE_PARAMETER_BOUND
|
||||||
null,
|
) { typeRef: Int, typePath: TypePath?, descriptor: String, visible: Boolean ->
|
||||||
descr,
|
methodVisitor.visitTypeAnnotation(typeRef, typePath, descriptor, visible)
|
||||||
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()) {
|
if (shouldGenerateAnnotationsOnValueParameters()) {
|
||||||
@@ -270,7 +229,7 @@ class FunctionCodegen(
|
|||||||
private fun generateAnnotationDefaultValueIfNeeded(methodVisitor: MethodVisitor) {
|
private fun generateAnnotationDefaultValueIfNeeded(methodVisitor: MethodVisitor) {
|
||||||
getAnnotationDefaultValueExpression()?.let { defaultValueExpression ->
|
getAnnotationDefaultValueExpression()?.let { defaultValueExpression ->
|
||||||
val annotationCodegen = object : AnnotationCodegen(classCodegen, context) {
|
val annotationCodegen = object : AnnotationCodegen(classCodegen, context) {
|
||||||
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
override fun visitAnnotation(descr: String, visible: Boolean): AnnotationVisitor {
|
||||||
return methodVisitor.visitAnnotationDefault()
|
return methodVisitor.visitAnnotationDefault()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,7 +290,7 @@ class FunctionCodegen(
|
|||||||
|
|
||||||
if (annotated != null && !kind.isSkippedInGenericSignature && !annotated.isSyntheticMarkerParameter()) {
|
if (annotated != null && !kind.isSkippedInGenericSignature && !annotated.isSyntheticMarkerParameter()) {
|
||||||
object : AnnotationCodegen(innerClassConsumer, context, skipNullabilityAnnotations) {
|
object : AnnotationCodegen(innerClassConsumer, context, skipNullabilityAnnotations) {
|
||||||
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
override fun visitAnnotation(descr: String, visible: Boolean): AnnotationVisitor {
|
||||||
return mv.visitParameterAnnotation(
|
return mv.visitParameterAnnotation(
|
||||||
i - syntheticParameterCount,
|
i - syntheticParameterCount,
|
||||||
descr,
|
descr,
|
||||||
@@ -339,7 +298,7 @@ class FunctionCodegen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
override fun visitTypeAnnotation(descr: String, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
||||||
return mv.visitTypeAnnotation(
|
return mv.visitTypeAnnotation(
|
||||||
TypeReference.newFormalParameterReference(i - syntheticParameterCount).value,
|
TypeReference.newFormalParameterReference(i - syntheticParameterCount).value,
|
||||||
path, descr, visible
|
path, descr, visible
|
||||||
|
|||||||
Reference in New Issue
Block a user