[K/JS] fix(KT-53569): skip double traversing for nested annotation classes.
This commit is contained in:
+22
-13
@@ -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 {
|
||||
|
||||
+5
-3
@@ -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
|
||||
|
||||
+6
@@ -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
|
||||
|
||||
+6
@@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user