JVM_IR: move classes out of lambdas inlined into initializers

Fixes KT-41465
This commit is contained in:
pyos
2020-08-31 13:12:58 +02:00
committed by Alexander Udalov
parent 9775a2148a
commit 6b65a2ea7d
9 changed files with 69 additions and 6 deletions

View File

@@ -28935,6 +28935,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
}
@TestMetadata("inlineIntoTwoConstructors.kt")
public void testInlineIntoTwoConstructors() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/innerClasses.kt");

View File

@@ -9,15 +9,29 @@ import org.jetbrains.kotlin.backend.common.ScopeWithIr
import org.jetbrains.kotlin.backend.common.lower.LocalClassPopupLowering
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.primaryConstructor
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class JvmLocalClassPopupLowering(context: JvmBackendContext) : LocalClassPopupLowering(context) {
private val inlineLambdaToScope = mutableMapOf<IrFunction, IrDeclaration>()
override fun lower(irFile: IrFile) {
irFile.accept(object : IrInlineReferenceLocator(context as JvmBackendContext) {
override fun visitInlineLambda(
argument: IrFunctionReference, callee: IrFunction, parameter: IrValueParameter, scope: IrDeclaration
) {
inlineLambdaToScope[argument.symbol.owner] = scope
}
}, null)
super.lower(irFile)
inlineLambdaToScope.clear()
}
// On JVM, we only pop up local classes in field initializers and anonymous init blocks, so that InitializersLowering would not copy
// them to each constructor. (Moving all local classes is not possible because of cases where they use reified type parameters,
// or capture crossinline lambdas.)
@@ -31,9 +45,13 @@ class JvmLocalClassPopupLowering(context: JvmBackendContext) : LocalClassPopupLo
klass.origin == JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE
if (!isLocal) return false
val container = when (val element = currentScope?.irElement) {
is IrAnonymousInitializer -> element.parentAsClass.takeUnless { element.isStatic }
is IrField -> element.parentAsClass.takeUnless { element.isStatic }
var parent = currentScope?.irElement
while (parent is IrFunction) {
parent = inlineLambdaToScope[parent] ?: break
}
val container = when (parent) {
is IrAnonymousInitializer -> parent.parentAsClass.takeUnless { parent.isStatic }
is IrField -> parent.parentAsClass.takeUnless { parent.isStatic }
else -> null
} ?: return false

View File

@@ -0,0 +1,10 @@
inline fun myRun(x: () -> String) = x()
class C {
val x = myRun { { "OK" }() }
constructor(y: Int)
constructor(y: String)
}
fun box(): String = C("").x

View File

@@ -30531,6 +30531,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
}
@TestMetadata("inlineIntoTwoConstructors.kt")
public void testInlineIntoTwoConstructors() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/innerClasses.kt");

View File

@@ -28165,6 +28165,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
}
@TestMetadata("inlineIntoTwoConstructors.kt")
public void testInlineIntoTwoConstructors() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/innerClasses.kt");

View File

@@ -28935,6 +28935,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
}
@TestMetadata("inlineIntoTwoConstructors.kt")
public void testInlineIntoTwoConstructors() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/innerClasses.kt");

View File

@@ -23521,6 +23521,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
}
@TestMetadata("inlineIntoTwoConstructors.kt")
public void testInlineIntoTwoConstructors() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/innerClasses.kt");

View File

@@ -23521,6 +23521,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
}
@TestMetadata("inlineIntoTwoConstructors.kt")
public void testInlineIntoTwoConstructors() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/innerClasses.kt");

View File

@@ -23536,6 +23536,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
}
@TestMetadata("inlineIntoTwoConstructors.kt")
public void testInlineIntoTwoConstructors() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt");
}
@TestMetadata("innerClasses.kt")
public void testInnerClasses() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/innerClasses.kt");