From 2fe9420ca1d08722dc173bfddf3deca56242b2b9 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Mon, 11 Oct 2021 17:10:19 +0300 Subject: [PATCH] Compatibility hack for instantiating annotations from old klibs ^KT-49181 --- .../AnnotationImplementationTransformer.kt | 18 ++++++++++++++++++ .../JsAnnotationImplementationLowering.kt | 14 ++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt index b70cd74b122..06dbd565241 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AnnotationImplementationTransformer.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.addConstructor import org.jetbrains.kotlin.ir.builders.declarations.buildClass @@ -18,6 +19,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull @@ -44,6 +46,22 @@ class AnnotationImplementationLowering( abstract class AnnotationImplementationTransformer(val context: BackendContext, val irFile: IrFile?) : IrElementTransformerVoidWithContext() { internal val implementations: MutableMap = mutableMapOf() + + override fun visitClassNew(declaration: IrClass): IrStatement { + declaration.takeIf { declaration.isAnnotationClass }?.constructors?.singleOrNull()?.apply { + // Compatibility hack. Now, frontend generates constructor body for annotations + // but, if one gets annotation from pre-1.6.20 klib, it would have none, so we need to generate it's body + if (body == null) { + body = context.createIrBuilder(symbol) + .irBlockBody(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET) { + +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single()) + +IrInstanceInitializerCallImpl(startOffset, endOffset, declaration.symbol, context.irBuiltIns.unitType) + } + } + } + return super.visitClassNew(declaration) + } + override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { val constructedClass = expression.type.classOrNull?.owner ?: return super.visitConstructorCall(expression) if (!constructedClass.isAnnotationClass) return super.visitConstructorCall(expression) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsAnnotationImplementationLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsAnnotationImplementationLowering.kt index 17483e8c8ea..cc051c3f978 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsAnnotationImplementationLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsAnnotationImplementationLowering.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer +import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder import org.jetbrains.kotlin.ir.builders.irCall @@ -30,7 +31,7 @@ class JsAnnotationImplementationTransformer(val jsContext: JsIrBackendContext) : DeclarationTransformer { override fun transformFlat(declaration: IrDeclaration): List? = - if (declaration is IrClass && declaration.isAnnotationClass) listOf(visitClassNew(declaration)) + if (declaration is IrClass && declaration.isAnnotationClass) listOf(visitClassNew(declaration) as IrClass) else null override fun visitConstructorCall(expression: IrConstructorCall): IrExpression { @@ -38,12 +39,13 @@ class JsAnnotationImplementationTransformer(val jsContext: JsIrBackendContext) : return expression } - override fun visitClassNew(declaration: IrClass): IrClass { - if (!declaration.isAnnotationClass) return declaration - context.irFactory.stageController.unrestrictDeclarationListsAccess { - implementGeneratedFunctions(declaration, declaration) + override fun visitClassNew(declaration: IrClass): IrStatement { + if (declaration.isAnnotationClass) { + context.irFactory.stageController.unrestrictDeclarationListsAccess { + implementGeneratedFunctions(declaration, declaration) + } } - return declaration + return super.visitClassNew(declaration) } private val arraysContentEquals: Map =