IR: Process script with LDL as if it is a function body
#KT-46645 fixed #KT-48025 fixed
This commit is contained in:
committed by
TeamCityServer
parent
ebcc6eec97
commit
e7cbc9a0fb
+6
@@ -40135,6 +40135,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testClassReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localCaptureTests.kt")
|
||||
public void testLocalCaptureTests() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/localCaptureTests.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.util.transformSubsetFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
@@ -64,6 +61,12 @@ interface BodyLoweringPass : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
interface BodyAndScriptBodyLoweringPass : BodyLoweringPass {
|
||||
fun lowerScriptBody(irDeclarationContainer: IrDeclarationContainer, container: IrDeclaration)
|
||||
|
||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) }
|
||||
|
||||
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
||||
@@ -129,7 +132,17 @@ fun BodyLoweringPass.runOnFilePostfix(
|
||||
}
|
||||
}
|
||||
|
||||
private class BodyLoweringVisitor(
|
||||
fun BodyAndScriptBodyLoweringPass.runOnFilePostfix(
|
||||
irFile: IrFile,
|
||||
allowDeclarationModification: Boolean = false
|
||||
) {
|
||||
val visitor = ScriptBodyLoweringVisitor(this, allowDeclarationModification)
|
||||
for (declaration in ArrayList(irFile.declarations)) {
|
||||
declaration.accept(visitor, null)
|
||||
}
|
||||
}
|
||||
|
||||
private open class BodyLoweringVisitor(
|
||||
private val loweringPass: BodyLoweringPass,
|
||||
private val withLocalDeclarations: Boolean,
|
||||
private val allowDeclarationModification: Boolean,
|
||||
@@ -168,6 +181,30 @@ private class BodyLoweringVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private class ScriptBodyLoweringVisitor(
|
||||
private val loweringPass: BodyAndScriptBodyLoweringPass,
|
||||
private val allowDeclarationModification: Boolean
|
||||
) : BodyLoweringVisitor(loweringPass, false, allowDeclarationModification) {
|
||||
|
||||
override fun visitClass(declaration: IrClass, data: IrDeclaration?) {
|
||||
declaration.thisReceiver?.accept(this, declaration)
|
||||
declaration.typeParameters.forEach { it.accept(this, declaration) }
|
||||
ArrayList(declaration.declarations).forEach { it.accept(this, declaration) }
|
||||
if (declaration.origin == IrDeclarationOrigin.SCRIPT_CLASS) {
|
||||
val stageController = declaration.factory.stageController
|
||||
stageController.restrictTo(declaration) {
|
||||
if (allowDeclarationModification) {
|
||||
loweringPass.lowerScriptBody(declaration, declaration)
|
||||
} else {
|
||||
stageController.bodyLowering {
|
||||
loweringPass.lowerScriptBody(declaration, declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface DeclarationTransformer : FileLoweringPass {
|
||||
fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>?
|
||||
|
||||
|
||||
+19
-7
@@ -5,11 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.BodyAndScriptBodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
|
||||
import org.jetbrains.kotlin.backend.common.ir.*
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
@@ -79,7 +80,7 @@ class LocalDeclarationsLowering(
|
||||
val visibilityPolicy: VisibilityPolicy = VisibilityPolicy.DEFAULT,
|
||||
val suggestUniqueNames: Boolean = true, // When `true` appends a `-#index` suffix to lifted declaration names
|
||||
) :
|
||||
BodyLoweringPass {
|
||||
BodyAndScriptBodyLoweringPass {
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
runOnFilePostfix(irFile, allowDeclarationModification = true)
|
||||
@@ -92,11 +93,16 @@ class LocalDeclarationsLowering(
|
||||
IrDeclarationOriginImpl("FIELD_FOR_CROSSINLINE_CAPTURED_VALUE", isSynthetic = true)
|
||||
|
||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||
LocalDeclarationsTransformer(irBody, container, null).lowerLocalDeclarations()
|
||||
LocalDeclarationsTransformer(irBody, container, null, false).lowerLocalDeclarations()
|
||||
}
|
||||
|
||||
override fun lowerScriptBody(irDeclarationContainer: IrDeclarationContainer, container: IrDeclaration) {
|
||||
LocalDeclarationsTransformer(irDeclarationContainer, container, null, true).lowerLocalDeclarations()
|
||||
}
|
||||
|
||||
|
||||
fun lower(irElement: IrElement, container: IrDeclaration, classesToLower: Set<IrClass>) {
|
||||
LocalDeclarationsTransformer(irElement, container, classesToLower).lowerLocalDeclarations()
|
||||
LocalDeclarationsTransformer(irElement, container, classesToLower, false).lowerLocalDeclarations()
|
||||
}
|
||||
|
||||
internal class ScopeWithCounter(val irElement: IrElement) {
|
||||
@@ -199,7 +205,7 @@ class LocalDeclarationsLowering(
|
||||
}
|
||||
|
||||
private inner class LocalDeclarationsTransformer(
|
||||
val irElement: IrElement, val container: IrDeclaration, val classesToLower: Set<IrClass>?
|
||||
val irElement: IrElement, val container: IrDeclaration, val classesToLower: Set<IrClass>?, val isScriptMode: Boolean
|
||||
) {
|
||||
val localFunctions: MutableMap<IrFunction, LocalFunctionContext> = LinkedHashMap()
|
||||
val localClasses: MutableMap<IrClass, LocalClassContext> = LinkedHashMap()
|
||||
@@ -461,6 +467,8 @@ class LocalDeclarationsLowering(
|
||||
|
||||
irClass.transformChildrenVoid(FunctionBodiesRewriter(localClassContext))
|
||||
|
||||
if (isScriptMode && constructors.isEmpty()) return
|
||||
|
||||
val constructorsCallingSuper = constructors
|
||||
.asSequence()
|
||||
.map { localClassConstructors[it]!! }
|
||||
@@ -928,7 +936,9 @@ class LocalDeclarationsLowering(
|
||||
override fun visitConstructor(declaration: IrConstructor, data: Data) {
|
||||
super.visitConstructor(declaration, data)
|
||||
|
||||
if (!declaration.constructedClass.isLocalNotInner()) return
|
||||
if (!isScriptMode && !declaration.constructedClass.isLocalNotInner()) return
|
||||
// LDL doesn't work on the enums because local enums are not allowed, so skipping them in scripts too
|
||||
if (isScriptMode && declaration.constructedClass.kind == ClassKind.ENUM_CLASS) return
|
||||
|
||||
localClassConstructors[declaration] = LocalClassConstructorContext(declaration, data.inInlineFunctionScope)
|
||||
}
|
||||
@@ -937,7 +947,9 @@ class LocalDeclarationsLowering(
|
||||
if (classesToLower?.contains(declaration) == false) return
|
||||
super.visitClass(declaration, data.withCurrentClass(declaration))
|
||||
|
||||
if (!declaration.isLocalNotInner()) return
|
||||
if (!isScriptMode && !declaration.isLocalNotInner()) return
|
||||
// LDL doesn't work on the enums because local enums are not allowed, so skipping them in scripts too
|
||||
if (isScriptMode && declaration.kind == ClassKind.ENUM_CLASS) return
|
||||
|
||||
localClasses[declaration] = LocalClassContext(declaration, data.inInlineFunctionScope)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_LIGHT_ANALYSIS
|
||||
// WITH_RUNTIME
|
||||
// FILE: test.kt
|
||||
|
||||
fun box(): String =
|
||||
Script.Build.Debug.run { "${c0()}${c1()}" }
|
||||
|
||||
// FILE: script.kts
|
||||
|
||||
interface Base {
|
||||
val v: String
|
||||
|
||||
fun c0(): Char {
|
||||
fun getC0() = v[0]
|
||||
return getC0()
|
||||
}
|
||||
}
|
||||
|
||||
enum class Build(override val v: String): Base {
|
||||
Debug("OK"),
|
||||
Release("NO");
|
||||
|
||||
fun c1(): Char {
|
||||
val g = object {
|
||||
val c1 = v[1]
|
||||
}
|
||||
return g.c1
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
|
||||
val p = 0
|
||||
|
||||
class ReducedFraction() {
|
||||
fun plus1() = reducedFractionOf(p)
|
||||
val y = 1
|
||||
}
|
||||
|
||||
fun reducedFractionOf(a: Int) {
|
||||
}
|
||||
|
||||
val c = ReducedFraction()
|
||||
val x = c.y
|
||||
// expected: x: 1
|
||||
+6
@@ -39961,6 +39961,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testClassReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localCaptureTests.kt")
|
||||
public void testLocalCaptureTests() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/localCaptureTests.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -40135,6 +40135,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testClassReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localCaptureTests.kt")
|
||||
public void testLocalCaptureTests() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/localCaptureTests.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+5
@@ -32025,6 +32025,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testClassReference() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localCaptureTests.kt")
|
||||
public void testLocalCaptureTests() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/script/localCaptureTests.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/sealed")
|
||||
|
||||
+5
@@ -74,6 +74,11 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
|
||||
runTest("compiler/testData/codegen/script/kt22029.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("kt48025.kts")
|
||||
public void testKt48025() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/kt48025.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("localDelegatedProperty.kts")
|
||||
public void testLocalDelegatedProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
|
||||
|
||||
+5
@@ -75,6 +75,11 @@ public class IrScriptCodegenTestGenerated extends AbstractIrScriptCodegenTest {
|
||||
runTest("compiler/testData/codegen/script/kt22029.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("kt48025.kts")
|
||||
public void testKt48025() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/kt48025.kts");
|
||||
}
|
||||
|
||||
@TestMetadata("localDelegatedProperty.kts")
|
||||
public void testLocalDelegatedProperty() throws Exception {
|
||||
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
|
||||
|
||||
Reference in New Issue
Block a user