JVM_IR: generate "safe" names for functions in init blocks

This commit is contained in:
Dmitry Petrov
2020-07-22 11:53:05 +03:00
parent bb8f857809
commit 1272162a7f
14 changed files with 209 additions and 6 deletions
@@ -4358,6 +4358,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitBlock.kt");
}
@TestMetadata("localFunctionInInitializer.kt")
public void testLocalFunctionInInitializer() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt");
@@ -570,12 +570,18 @@ class LocalDeclarationsLowering(
private fun generateNameForLiftedDeclaration(
declaration: IrDeclaration,
newOwner: IrDeclarationParent
): Name =
Name.identifier(
declaration.parentsWithSelf
.takeWhile { it != newOwner }
.toList().reversed().joinToString(separator = "$") { suggestLocalName(it as IrDeclarationWithName) }
)
): Name {
val parents = declaration.parentsWithSelf.takeWhile { it != newOwner }.toList().reversed()
val nameFromParents = parents.joinToString(separator = "$") { suggestLocalName(it as IrDeclarationWithName) }
// Local functions declared in anonymous initializers have classes as their parents.
// Such anonymous initializers, however, are inlined into the constructors delegating to super class constructor.
// There can be local functions declared in local function in init blocks (and further),
// but such functions would have proper "safe" names (outerLocalFun1$outerLocalFun2$...$localFun).
return if (parents.size == 1 && declaration.parent is IrClass)
Name.identifier("_init_\$$nameFromParents")
else
Name.identifier(nameFromParents)
}
private fun createLiftedDeclaration(localFunctionContext: LocalFunctionContext) {
val oldDeclaration = localFunctionContext.declaration
@@ -0,0 +1,28 @@
// IGNORE_BACKEND_FIR: JVM_IR
lateinit var result1: String
lateinit var result2: String
class Test(val x: String) {
fun test(a: String) {
if (result1 != a) throw AssertionError("result1: $result1")
result2 = a
}
init {
fun test() {
fun test1() {
result1 = x
}
test1()
}
test()
}
}
fun box(): String {
val t = Test("OK")
t.test("OK")
return result2
}
@@ -0,0 +1,23 @@
class C() {
constructor(x: Int): this() {
fun test() {
fun test() {}
}
}
constructor(y: String): this() {
fun test() {
fun test() {}
}
}
fun test() {
fun test() {}
}
init {
fun test() {
fun test() {}
}
}
}
@@ -0,0 +1,87 @@
@kotlin.Metadata
final class C$1$1 {
public final static field INSTANCE: C$1$1
inner (anonymous) class C$1
inner (anonymous) class C$1$1
static method <clinit>(): void
method <init>(): void
public synthetic bridge method invoke(): java.lang.Object
public final method invoke(): void
}
@kotlin.Metadata
final class C$1 {
public final static field INSTANCE: C$1
inner (anonymous) class C$1
inner (anonymous) class C$1$1
static method <clinit>(): void
method <init>(): void
public synthetic bridge method invoke(): java.lang.Object
public final method invoke(): void
}
@kotlin.Metadata
final class C$2$1 {
public final static field INSTANCE: C$2$1
inner (anonymous) class C$2
inner (anonymous) class C$2$1
static method <clinit>(): void
method <init>(): void
public synthetic bridge method invoke(): java.lang.Object
public final method invoke(): void
}
@kotlin.Metadata
final class C$2 {
public final static field INSTANCE: C$2
inner (anonymous) class C$2
inner (anonymous) class C$2$1
static method <clinit>(): void
method <init>(): void
public synthetic bridge method invoke(): java.lang.Object
public final method invoke(): void
}
@kotlin.Metadata
final class C$3$1 {
public final static field INSTANCE: C$3$1
inner (anonymous) class C$3
inner (anonymous) class C$3$1
static method <clinit>(): void
method <init>(): void
public synthetic bridge method invoke(): java.lang.Object
public final method invoke(): void
}
@kotlin.Metadata
final class C$3 {
public final static field INSTANCE: C$3
inner (anonymous) class C$3
inner (anonymous) class C$3$1
static method <clinit>(): void
method <init>(): void
public synthetic bridge method invoke(): java.lang.Object
public final method invoke(): void
}
@kotlin.Metadata
final class C$test$1 {
public final static field INSTANCE: C$test$1
inner (anonymous) class C$test$1
static method <clinit>(): void
method <init>(): void
public synthetic bridge method invoke(): java.lang.Object
public final method invoke(): void
}
@kotlin.Metadata
public final class C {
inner (anonymous) class C$1
inner (anonymous) class C$2
inner (anonymous) class C$3
inner (anonymous) class C$test$1
public method <init>(): void
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
public method <init>(p0: int): void
public final method test(): void
}
@@ -0,0 +1,14 @@
@kotlin.Metadata
public final class C {
public method <init>(): void
public method <init>(@org.jetbrains.annotations.NotNull p0: java.lang.String): void
public method <init>(p0: int): void
private final static method _init_$test-0$test(): void
private final static method _init_$test-0(): void
private final static method _init_$test-2$test-1(): void
private final static method _init_$test-2(): void
private final static method _init_$test-5(): void
private final static method test$test-3(): void
public final method test(): void
private final static method test-5$test-4(): void
}
@@ -4378,6 +4378,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitBlock.kt");
}
@TestMetadata("localFunctionInInitializer.kt")
public void testLocalFunctionInInitializer() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt");
@@ -99,6 +99,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
runTest("compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt");
}
@TestMetadata("noCollectionStubMethodsInInterface.kt")
public void testNoCollectionStubMethodsInInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt");
@@ -4378,6 +4378,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitBlock.kt");
}
@TestMetadata("localFunctionInInitializer.kt")
public void testLocalFunctionInInitializer() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt");
@@ -4358,6 +4358,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitBlock.kt");
}
@TestMetadata("localFunctionInInitializer.kt")
public void testLocalFunctionInInitializer() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt");
@@ -99,6 +99,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
runTest("compiler/testData/codegen/bytecodeListing/lateInitNotNull.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt");
}
@TestMetadata("noCollectionStubMethodsInInterface.kt")
public void testNoCollectionStubMethodsInInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt");
@@ -3608,6 +3608,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitBlock.kt");
}
@TestMetadata("localFunctionInInitializer.kt")
public void testLocalFunctionInInitializer() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt");
@@ -3608,6 +3608,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitBlock.kt");
}
@TestMetadata("localFunctionInInitializer.kt")
public void testLocalFunctionInInitializer() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt");
@@ -3608,6 +3608,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt");
}
@TestMetadata("localFunctionInInitBlock.kt")
public void testLocalFunctionInInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitBlock.kt");
}
@TestMetadata("localFunctionInInitializer.kt")
public void testLocalFunctionInInitializer() throws Exception {
runTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt");