JVM_IR: No nullability annotations on static lambda instances
This commit is contained in:
@@ -50,4 +50,5 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
|
|||||||
object FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE : IrDeclarationOriginImpl("FOR_INLINE_TEMPLATE_CROSSINLINE")
|
object FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE : IrDeclarationOriginImpl("FOR_INLINE_TEMPLATE_CROSSINLINE")
|
||||||
object CONTINUATION_CLASS_RESULT_FIELD: IrDeclarationOriginImpl("CONTINUATION_CLASS_RESULT_FIELD", isSynthetic = true)
|
object CONTINUATION_CLASS_RESULT_FIELD: IrDeclarationOriginImpl("CONTINUATION_CLASS_RESULT_FIELD", isSynthetic = true)
|
||||||
object COMPANION_PROPERTY_BACKING_FIELD : IrDeclarationOriginImpl("COMPANION_MOVED_PROPERTY_BACKING_FIELD")
|
object COMPANION_PROPERTY_BACKING_FIELD : IrDeclarationOriginImpl("COMPANION_MOVED_PROPERTY_BACKING_FIELD")
|
||||||
|
object FIELD_FOR_STATIC_LAMBDA_INSTANCE : IrDeclarationOriginImpl("FIELD_FOR_STATIC_LAMBDA_INSTANCE")
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -235,21 +235,25 @@ abstract class ClassCodegen protected constructor(
|
|||||||
if (field.origin == IrDeclarationOrigin.PROPERTY_DELEGATE) null
|
if (field.origin == IrDeclarationOrigin.PROPERTY_DELEGATE) null
|
||||||
else context.methodSignatureMapper.mapFieldSignature(field)
|
else context.methodSignatureMapper.mapFieldSignature(field)
|
||||||
val fieldName = field.name.asString()
|
val fieldName = field.name.asString()
|
||||||
|
val flags = field.flags
|
||||||
val fv = visitor.newField(
|
val fv = visitor.newField(
|
||||||
field.OtherOrigin, field.flags, fieldName, fieldType.descriptor,
|
field.OtherOrigin, flags, fieldName, fieldType.descriptor,
|
||||||
fieldSignature, (field.initializer?.expression as? IrConst<*>)?.value
|
fieldSignature, (field.initializer?.expression as? IrConst<*>)?.value
|
||||||
)
|
)
|
||||||
|
|
||||||
jvmSignatureClashDetector.trackField(field, RawSignature(fieldName, fieldType.descriptor, MemberKind.FIELD))
|
jvmSignatureClashDetector.trackField(field, RawSignature(fieldName, fieldType.descriptor, MemberKind.FIELD))
|
||||||
|
|
||||||
if (field.origin != JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD) {
|
if (field.origin != JvmLoweredDeclarationOrigin.CONTINUATION_CLASS_RESULT_FIELD) {
|
||||||
object : AnnotationCodegen(this@ClassCodegen, context) {
|
val skipNullabilityAnnotations =
|
||||||
|
flags and Opcodes.ACC_SYNTHETIC != 0 || flags and Opcodes.ACC_PRIVATE != 0 ||
|
||||||
|
field.origin == JvmLoweredDeclarationOrigin.FIELD_FOR_STATIC_LAMBDA_INSTANCE
|
||||||
|
object : AnnotationCodegen(this@ClassCodegen, context, skipNullabilityAnnotations) {
|
||||||
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
override fun visitAnnotation(descr: String?, visible: Boolean): AnnotationVisitor {
|
||||||
return fv.visitAnnotation(descr, visible)
|
return fv.visitAnnotation(descr, visible)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
override fun visitTypeAnnotation(descr: String?, path: TypePath?, visible: Boolean): AnnotationVisitor {
|
||||||
return fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).value,path, descr, visible)
|
return fv.visitTypeAnnotation(TypeReference.newTypeReference(TypeReference.FIELD).value, path, descr, visible)
|
||||||
}
|
}
|
||||||
}.genAnnotations(field, fieldType, field.type)
|
}.genAnnotations(field, fieldType, field.type)
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-3
@@ -10,24 +10,30 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
|||||||
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.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||||
import org.jetbrains.kotlin.ir.builders.irCall
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
import org.jetbrains.kotlin.ir.builders.irExprBody
|
import org.jetbrains.kotlin.ir.builders.irExprBody
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||||
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.primaryConstructor
|
import org.jetbrains.kotlin.ir.util.primaryConstructor
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
internal val staticLambdaPhase = makeIrFilePhase(
|
internal val staticLambdaPhase = makeIrFilePhase(
|
||||||
::StaticLambdaLowering,
|
::StaticLambdaLowering,
|
||||||
@@ -36,12 +42,14 @@ internal val staticLambdaPhase = makeIrFilePhase(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class StaticLambdaLowering(val backendContext: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() {
|
class StaticLambdaLowering(val backendContext: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() {
|
||||||
|
private val staticLambdaFields = HashMap<IrClass, IrField>()
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) = irFile.transformChildrenVoid()
|
override fun lower(irFile: IrFile) = irFile.transformChildrenVoid()
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass): IrStatement {
|
override fun visitClass(declaration: IrClass): IrStatement {
|
||||||
declaration.transformChildrenVoid()
|
declaration.transformChildrenVoid()
|
||||||
if (declaration.isSyntheticSingleton) {
|
if (declaration.isSyntheticSingleton) {
|
||||||
declaration.declarations += backendContext.declarationFactory.getFieldForObjectInstance(declaration).also { field ->
|
declaration.declarations += getFieldForStaticLambdaInstance(declaration).also { field ->
|
||||||
field.initializer = backendContext.createIrBuilder(field.symbol).run {
|
field.initializer = backendContext.createIrBuilder(field.symbol).run {
|
||||||
irExprBody(irCall(declaration.primaryConstructor!!))
|
irExprBody(irCall(declaration.primaryConstructor!!))
|
||||||
}
|
}
|
||||||
@@ -50,12 +58,26 @@ class StaticLambdaLowering(val backendContext: JvmBackendContext) : FileLowering
|
|||||||
return declaration
|
return declaration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getFieldForStaticLambdaInstance(lambdaClass: IrClass): IrField =
|
||||||
|
staticLambdaFields.getOrPut(lambdaClass) {
|
||||||
|
buildField {
|
||||||
|
name = Name.identifier(JvmAbi.INSTANCE_FIELD)
|
||||||
|
type = lambdaClass.defaultType
|
||||||
|
origin = JvmLoweredDeclarationOrigin.FIELD_FOR_STATIC_LAMBDA_INSTANCE
|
||||||
|
isFinal = true
|
||||||
|
isStatic = true
|
||||||
|
visibility = Visibilities.PUBLIC
|
||||||
|
}.apply {
|
||||||
|
parent = lambdaClass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||||
val constructor = expression.symbol.owner
|
val constructor = expression.symbol.owner
|
||||||
if (!constructor.constructedClass.isSyntheticSingleton)
|
if (!constructor.constructedClass.isSyntheticSingleton)
|
||||||
return super.visitConstructorCall(expression)
|
return super.visitConstructorCall(expression)
|
||||||
|
|
||||||
val instanceField = backendContext.declarationFactory.getFieldForObjectInstance(constructor.constructedClass)
|
val instanceField = getFieldForStaticLambdaInstance(constructor.constructedClass)
|
||||||
return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceField.symbol, expression.type)
|
return IrGetFieldImpl(expression.startOffset, expression.endOffset, instanceField.symbol, expression.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ public final class Override5Kt$inlineMe$1$generic$1 {
|
|||||||
|
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class Override5Kt$inlineMe$1$generic$2 {
|
public final class Override5Kt$inlineMe$1$generic$2 {
|
||||||
public final static @org.jetbrains.annotations.NotNull field INSTANCE: Override5Kt$inlineMe$1$generic$2
|
public final static field INSTANCE: Override5Kt$inlineMe$1$generic$2
|
||||||
inner (anonymous) class Override5Kt$inlineMe$1
|
inner (anonymous) class Override5Kt$inlineMe$1
|
||||||
inner (anonymous) class Override5Kt$inlineMe$1$generic$2
|
inner (anonymous) class Override5Kt$inlineMe$1$generic$2
|
||||||
static method <clinit>(): void
|
static method <clinit>(): void
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
annotation class Ann
|
annotation class Ann
|
||||||
|
|
||||||
@Ann open class My
|
@Ann open class My
|
||||||
|
|||||||
Reference in New Issue
Block a user