IR: Process script with LDL as if it is a function body

#KT-46645 fixed
#KT-48025 fixed
This commit is contained in:
Ilya Chernikov
2021-08-13 14:36:17 +02:00
committed by TeamCityServer
parent ebcc6eec97
commit e7cbc9a0fb
10 changed files with 138 additions and 11 deletions
@@ -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>?
@@ -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
View File
@@ -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
@@ -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
@@ -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
@@ -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")
@@ -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");
@@ -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");