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 {
|
public void testClassReference() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
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
|
@Nested
|
||||||
|
|||||||
@@ -17,12 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.backend.common
|
package org.jetbrains.kotlin.backend.common
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.IrBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
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.transformFlat
|
||||||
import org.jetbrains.kotlin.ir.util.transformSubsetFlat
|
import org.jetbrains.kotlin.ir.util.transformSubsetFlat
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
@@ -64,6 +61,12 @@ interface BodyLoweringPass : FileLoweringPass {
|
|||||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
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 FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) }
|
||||||
|
|
||||||
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
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 loweringPass: BodyLoweringPass,
|
||||||
private val withLocalDeclarations: Boolean,
|
private val withLocalDeclarations: Boolean,
|
||||||
private val allowDeclarationModification: 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 {
|
interface DeclarationTransformer : FileLoweringPass {
|
||||||
fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>?
|
fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>?
|
||||||
|
|
||||||
|
|||||||
+19
-7
@@ -5,11 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.lower
|
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.CommonBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.BodyAndScriptBodyLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
|
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
|
||||||
import org.jetbrains.kotlin.backend.common.ir.*
|
import org.jetbrains.kotlin.backend.common.ir.*
|
||||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||||
@@ -79,7 +80,7 @@ class LocalDeclarationsLowering(
|
|||||||
val visibilityPolicy: VisibilityPolicy = VisibilityPolicy.DEFAULT,
|
val visibilityPolicy: VisibilityPolicy = VisibilityPolicy.DEFAULT,
|
||||||
val suggestUniqueNames: Boolean = true, // When `true` appends a `-#index` suffix to lifted declaration names
|
val suggestUniqueNames: Boolean = true, // When `true` appends a `-#index` suffix to lifted declaration names
|
||||||
) :
|
) :
|
||||||
BodyLoweringPass {
|
BodyAndScriptBodyLoweringPass {
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
runOnFilePostfix(irFile, allowDeclarationModification = true)
|
runOnFilePostfix(irFile, allowDeclarationModification = true)
|
||||||
@@ -92,11 +93,16 @@ class LocalDeclarationsLowering(
|
|||||||
IrDeclarationOriginImpl("FIELD_FOR_CROSSINLINE_CAPTURED_VALUE", isSynthetic = true)
|
IrDeclarationOriginImpl("FIELD_FOR_CROSSINLINE_CAPTURED_VALUE", isSynthetic = true)
|
||||||
|
|
||||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
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>) {
|
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) {
|
internal class ScopeWithCounter(val irElement: IrElement) {
|
||||||
@@ -199,7 +205,7 @@ class LocalDeclarationsLowering(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inner class LocalDeclarationsTransformer(
|
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 localFunctions: MutableMap<IrFunction, LocalFunctionContext> = LinkedHashMap()
|
||||||
val localClasses: MutableMap<IrClass, LocalClassContext> = LinkedHashMap()
|
val localClasses: MutableMap<IrClass, LocalClassContext> = LinkedHashMap()
|
||||||
@@ -461,6 +467,8 @@ class LocalDeclarationsLowering(
|
|||||||
|
|
||||||
irClass.transformChildrenVoid(FunctionBodiesRewriter(localClassContext))
|
irClass.transformChildrenVoid(FunctionBodiesRewriter(localClassContext))
|
||||||
|
|
||||||
|
if (isScriptMode && constructors.isEmpty()) return
|
||||||
|
|
||||||
val constructorsCallingSuper = constructors
|
val constructorsCallingSuper = constructors
|
||||||
.asSequence()
|
.asSequence()
|
||||||
.map { localClassConstructors[it]!! }
|
.map { localClassConstructors[it]!! }
|
||||||
@@ -928,7 +936,9 @@ class LocalDeclarationsLowering(
|
|||||||
override fun visitConstructor(declaration: IrConstructor, data: Data) {
|
override fun visitConstructor(declaration: IrConstructor, data: Data) {
|
||||||
super.visitConstructor(declaration, 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)
|
localClassConstructors[declaration] = LocalClassConstructorContext(declaration, data.inInlineFunctionScope)
|
||||||
}
|
}
|
||||||
@@ -937,7 +947,9 @@ class LocalDeclarationsLowering(
|
|||||||
if (classesToLower?.contains(declaration) == false) return
|
if (classesToLower?.contains(declaration) == false) return
|
||||||
super.visitClass(declaration, data.withCurrentClass(declaration))
|
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)
|
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 {
|
public void testClassReference() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
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
|
@Nested
|
||||||
|
|||||||
+6
@@ -40135,6 +40135,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testClassReference() throws Exception {
|
public void testClassReference() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
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
|
@Nested
|
||||||
|
|||||||
+5
@@ -32025,6 +32025,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
public void testClassReference() throws Exception {
|
public void testClassReference() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/script/classReference.kt");
|
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")
|
@TestMetadata("compiler/testData/codegen/box/sealed")
|
||||||
|
|||||||
+5
@@ -74,6 +74,11 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/script/kt22029.kts");
|
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")
|
@TestMetadata("localDelegatedProperty.kts")
|
||||||
public void testLocalDelegatedProperty() throws Exception {
|
public void testLocalDelegatedProperty() throws Exception {
|
||||||
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
|
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
|
||||||
|
|||||||
+5
@@ -75,6 +75,11 @@ public class IrScriptCodegenTestGenerated extends AbstractIrScriptCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/script/kt22029.kts");
|
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")
|
@TestMetadata("localDelegatedProperty.kts")
|
||||||
public void testLocalDelegatedProperty() throws Exception {
|
public void testLocalDelegatedProperty() throws Exception {
|
||||||
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
|
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
|
||||||
|
|||||||
Reference in New Issue
Block a user