[K/JS] fix(KT-53569): skip double traversing for nested annotation classes.

This commit is contained in:
Artem Kobzar
2022-08-18 16:39:48 +00:00
committed by Space
parent 7441388f9d
commit 8e17c39cc9
6 changed files with 56 additions and 16 deletions
@@ -47,22 +47,31 @@ abstract class AnnotationImplementationTransformer(val context: BackendContext,
override fun visitClassNew(declaration: IrClass): IrStatement {
declaration.takeIf { declaration.isAnnotationClass }?.constructors?.singleOrNull()?.apply {
// Compatibility hack. Now, frontend generates constructor body for annotations and makes them open
// but, if one gets annotation from pre-1.6.20 klib, it would have no constructor body and would be final,
// so we need to fix it
if (body == null) {
declaration.modality = Modality.OPEN
body = context.createIrBuilder(symbol)
.irBlockBody(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET) {
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
+IrInstanceInitializerCallImpl(startOffset, endOffset, declaration.symbol, context.irBuiltIns.unitType)
}
}
}
declaration.addConstructorBodyForCompatibility()
return super.visitClassNew(declaration)
}
protected fun IrClass.addConstructorBodyForCompatibility() {
if (!isAnnotationClass) return
val primaryConstructor = constructors.singleOrNull() ?: return
if (primaryConstructor.body != null) return
// Compatibility hack. Now, frontend generates constructor body for annotations and makes them open
// but, if one gets annotation from pre-1.6.20 klib, it would have no constructor body and would be final,
// so we need to fix it
modality = Modality.OPEN
primaryConstructor.body = context.createIrBuilder(symbol)
.irBlockBody(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET) {
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
+IrInstanceInitializerCallImpl(
startOffset,
endOffset,
this@addConstructorBodyForCompatibility.symbol,
context.irBuiltIns.unitType
)
}
}
abstract fun chooseConstructor(implClass: IrClass, expression: IrConstructorCall) : IrConstructor
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
@@ -40,10 +40,12 @@ class JsAnnotationImplementationTransformer(val jsContext: JsIrBackendContext) :
compilationException("Should not be called", implClass)
override fun visitClassNew(declaration: IrClass): IrStatement {
if (declaration.isAnnotationClass) {
implementGeneratedFunctions(declaration, declaration)
return declaration.apply {
if (isAnnotationClass) {
implementGeneratedFunctions(this, this)
}
addConstructorBodyForCompatibility()
}
return super.visitClassNew(declaration)
}
private val arraysContentEquals: Map<IrType, IrSimpleFunctionSymbol> =
@@ -39,6 +39,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
public void testAnnotationClass() throws Exception {
runTest("js/js.translator/testData/box/annotation/annotationClass.kt");
}
@Test
@TestMetadata("multipleEqualMethodsBug.kt")
public void testMultipleEqualMethodsBug() throws Exception {
runTest("js/js.translator/testData/box/annotation/multipleEqualMethodsBug.kt");
}
}
@Nested
@@ -39,6 +39,12 @@ public class FirJsTestGenerated extends AbstractFirJsTest {
public void testAnnotationClass() throws Exception {
runTest("js/js.translator/testData/box/annotation/annotationClass.kt");
}
@Test
@TestMetadata("multipleEqualMethodsBug.kt")
public void testMultipleEqualMethodsBug() throws Exception {
runTest("js/js.translator/testData/box/annotation/multipleEqualMethodsBug.kt");
}
}
@Nested
@@ -39,6 +39,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
public void testAnnotationClass() throws Exception {
runTest("js/js.translator/testData/box/annotation/annotationClass.kt");
}
@Test
@TestMetadata("multipleEqualMethodsBug.kt")
public void testMultipleEqualMethodsBug() throws Exception {
runTest("js/js.translator/testData/box/annotation/multipleEqualMethodsBug.kt");
}
}
@Nested
@@ -0,0 +1,11 @@
// IGNORE_BACKEND: JS
// EXPECTED_REACHABLE_NODES: 1280
package foo
annotation class Parent {
annotation class Child
}
fun box(): String {
return if (Parent.Child() == Parent.Child()) "OK" else "FAIL"
}