jvm-abi-gen: Mark annotation implementation classes as public...
...if they are used from public inline functions in the same file.
This commit is contained in:
committed by
Alexander Udalov
parent
6756420725
commit
8de6a5224f
+5
-2
@@ -258,13 +258,16 @@ class ClassCodegen private constructor(
|
|||||||
extraFlags = extraFlags or JvmAnnotationNames.METADATA_SCRIPT_FLAG
|
extraFlags = extraFlags or JvmAnnotationNames.METADATA_SCRIPT_FLAG
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are three kinds of classes which are regenerated during inlining.
|
// There are four kinds of classes which are regenerated during inlining.
|
||||||
// 1) Anonymous classes which are in the scope of an inline function.
|
// 1) Anonymous classes which are in the scope of an inline function.
|
||||||
// 2) SAM wrappers used in an inline function. These are identified by name, since they
|
// 2) SAM wrappers used in an inline function. These are identified by name, since they
|
||||||
// can be reused in different functions and are thus generated in the enclosing top-level
|
// can be reused in different functions and are thus generated in the enclosing top-level
|
||||||
// class instead of inside of an inline function.
|
// class instead of inside of an inline function.
|
||||||
// 3) WhenMapping classes used from inline functions. These are collected in
|
// 3) WhenMapping classes used from public inline functions. These are collected in
|
||||||
// `JvmBackendContext.publicAbiSymbols` in `MappedEnumWhenLowering`.
|
// `JvmBackendContext.publicAbiSymbols` in `MappedEnumWhenLowering`.
|
||||||
|
// 4) Annotation implementation classes used from public inline function. Similar to
|
||||||
|
// public WhenMapping classes, these are collected in `publicAbiSymbols` in
|
||||||
|
// `JvmAnnotationImplementationTransformer`.
|
||||||
val isPublicAbi = irClass.symbol in context.publicAbiSymbols || irClass.isInlineSamWrapper ||
|
val isPublicAbi = irClass.symbol in context.publicAbiSymbols || irClass.isInlineSamWrapper ||
|
||||||
type.isAnonymousClass && irClass.isInPublicInlineScope
|
type.isAnonymousClass && irClass.isInPublicInlineScope
|
||||||
|
|
||||||
|
|||||||
+26
-4
@@ -11,18 +11,20 @@ import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransfo
|
|||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.ir.isInPublicInlineScope
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.FunctionReferenceLowering.Companion.javaClassReference
|
import org.jetbrains.kotlin.backend.jvm.lower.FunctionReferenceLowering.Companion.javaClassReference
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.findDeclaration
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.kotlin.ir.util.isPrimitiveArray
|
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
|
||||||
|
|
||||||
internal val annotationImplementationPhase = makeIrFilePhase<JvmBackendContext>(
|
internal val annotationImplementationPhase = makeIrFilePhase<JvmBackendContext>(
|
||||||
{ ctxt -> AnnotationImplementationLowering { JvmAnnotationImplementationTransformer(ctxt, it) } },
|
{ ctxt -> AnnotationImplementationLowering { JvmAnnotationImplementationTransformer(ctxt, it) } },
|
||||||
@@ -32,6 +34,20 @@ internal val annotationImplementationPhase = makeIrFilePhase<JvmBackendContext>(
|
|||||||
|
|
||||||
class JvmAnnotationImplementationTransformer(val jvmContext: JvmBackendContext, file: IrFile) :
|
class JvmAnnotationImplementationTransformer(val jvmContext: JvmBackendContext, file: IrFile) :
|
||||||
AnnotationImplementationTransformer(jvmContext, file) {
|
AnnotationImplementationTransformer(jvmContext, file) {
|
||||||
|
private val publicAnnotationImplementationClasses = mutableSetOf<IrClassSymbol>()
|
||||||
|
|
||||||
|
// FIXME: Copied from JvmSingleAbstractMethodLowering
|
||||||
|
private val inInlineFunctionScope: Boolean
|
||||||
|
get() = allScopes.any { it.irElement.safeAs<IrDeclaration>()?.isInPublicInlineScope == true }
|
||||||
|
|
||||||
|
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||||
|
val constructedClass = expression.type.classOrNull
|
||||||
|
if (constructedClass?.owner?.isAnnotationClass == true && inInlineFunctionScope) {
|
||||||
|
publicAnnotationImplementationClasses += constructedClass
|
||||||
|
}
|
||||||
|
return super.visitConstructorCall(expression)
|
||||||
|
}
|
||||||
|
|
||||||
override fun IrType.kClassToJClassIfNeeded(): IrType = when {
|
override fun IrType.kClassToJClassIfNeeded(): IrType = when {
|
||||||
this.isKClass() -> jvmContext.ir.symbols.javaLangClass.starProjectedType
|
this.isKClass() -> jvmContext.ir.symbols.javaLangClass.starProjectedType
|
||||||
this.isKClassArray() -> jvmContext.irBuiltIns.arrayClass.typeWith(
|
this.isKClassArray() -> jvmContext.irBuiltIns.arrayClass.typeWith(
|
||||||
@@ -72,6 +88,12 @@ class JvmAnnotationImplementationTransformer(val jvmContext: JvmBackendContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun implementPlatformSpecificParts(annotationClass: IrClass, implClass: IrClass) {
|
override fun implementPlatformSpecificParts(annotationClass: IrClass, implClass: IrClass) {
|
||||||
|
// Mark the implClass as part of the public ABI if it was instantiated from a public
|
||||||
|
// inline function, since annotation implementation classes are regenerated during inlining.
|
||||||
|
if (annotationClass.symbol in publicAnnotationImplementationClasses) {
|
||||||
|
jvmContext.publicAbiSymbols += implClass.symbol
|
||||||
|
}
|
||||||
|
|
||||||
implClass.addFunction(
|
implClass.addFunction(
|
||||||
name = "annotationType",
|
name = "annotationType",
|
||||||
returnType = jvmContext.ir.symbols.javaLangClass.starProjectedType,
|
returnType = jvmContext.ir.symbols.javaLangClass.starProjectedType,
|
||||||
|
|||||||
Reference in New Issue
Block a user