[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 {
|
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||||
declaration.takeIf { declaration.isAnnotationClass }?.constructors?.singleOrNull()?.apply {
|
declaration.addConstructorBodyForCompatibility()
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.visitClassNew(declaration)
|
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
|
abstract fun chooseConstructor(implClass: IrClass, expression: IrConstructorCall) : IrConstructor
|
||||||
|
|
||||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||||
|
|||||||
+5
-3
@@ -40,10 +40,12 @@ class JsAnnotationImplementationTransformer(val jsContext: JsIrBackendContext) :
|
|||||||
compilationException("Should not be called", implClass)
|
compilationException("Should not be called", implClass)
|
||||||
|
|
||||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||||
if (declaration.isAnnotationClass) {
|
return declaration.apply {
|
||||||
implementGeneratedFunctions(declaration, declaration)
|
if (isAnnotationClass) {
|
||||||
|
implementGeneratedFunctions(this, this)
|
||||||
|
}
|
||||||
|
addConstructorBodyForCompatibility()
|
||||||
}
|
}
|
||||||
return super.visitClassNew(declaration)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val arraysContentEquals: Map<IrType, IrSimpleFunctionSymbol> =
|
private val arraysContentEquals: Map<IrType, IrSimpleFunctionSymbol> =
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
public void testAnnotationClass() throws Exception {
|
public void testAnnotationClass() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/annotation/annotationClass.kt");
|
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
|
@Nested
|
||||||
|
|||||||
+6
@@ -39,6 +39,12 @@ public class FirJsTestGenerated extends AbstractFirJsTest {
|
|||||||
public void testAnnotationClass() throws Exception {
|
public void testAnnotationClass() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/annotation/annotationClass.kt");
|
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
|
@Nested
|
||||||
|
|||||||
+6
@@ -39,6 +39,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
|||||||
public void testAnnotationClass() throws Exception {
|
public void testAnnotationClass() throws Exception {
|
||||||
runTest("js/js.translator/testData/box/annotation/annotationClass.kt");
|
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
|
@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