mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
JVM_IR: move classes out of lambdas inlined into initializers
Fixes KT-41465
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
10
compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt
vendored
Normal file
10
compiler/testData/codegen/box/secondaryConstructors/inlineIntoTwoConstructors.kt
vendored
Normal 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
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user