Scripting: fix script lowering in case of out of order declarations

The problem was that in K2 for some top-level script declarations we
need to add a dispatch receiver parameter (because frontend do not
assign any, but representing script as a class requires it to be the
script class) and at the same time, calls to these declarations rely on
properly set dispatch receiver parameter.
The simplest solution found is to have an additional traversal on the
relevan top-level declarations and assigning the dispatch receiver,
before running the main transformation.

#KT-64502 fixed
This commit is contained in:
Ilya Chernikov
2024-02-15 12:32:04 +01:00
committed by Space Team
parent 266447120d
commit eab5164993
8 changed files with 102 additions and 2 deletions
@@ -201,6 +201,8 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext, val inner
)
val lambdaPatcher = ScriptFixLambdasTransformer(irScriptClass)
irScript.patchDeclarationsDispatchReceiver(context, scriptTransformer.scriptClassReceiver.type)
irScriptClass.thisReceiver = scriptTransformer.scriptClassReceiver
fun <E : IrElement> E.patchDeclarationForClass(): IrElement {
@@ -439,6 +441,26 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext, val inner
}
}
private fun IrScript.patchDeclarationsDispatchReceiver(context: JvmBackendContext, scriptClassReceiverType: IrType) {
fun IrFunction.addScriptDispatchReceiverIfNeeded() {
if (dispatchReceiverParameter == null) {
dispatchReceiverParameter =
createThisReceiverParameter(context, IrDeclarationOrigin.SCRIPT_THIS_RECEIVER, scriptClassReceiverType)
}
}
statements.forEach { scriptStatement ->
when (scriptStatement) {
is IrProperty -> {
scriptStatement.getter?.addScriptDispatchReceiverIfNeeded()
scriptStatement.setter?.addScriptDispatchReceiverIfNeeded()
}
is IrFunction -> scriptStatement.addScriptDispatchReceiverIfNeeded()
}
}
}
private fun IrBuilderWithScope.makeScriptClassConstructorBody(
irScript: IrScript,
irScriptClass: IrClass,
+23
View File
@@ -0,0 +1,23 @@
MODULE main
CLASS Kt48025.class
CLASS METADATA
K1
<init>([Ljava/lang/String;)V
K2
---
Property: class.metadata.superTypes
K1
[kotlin/script/templates/standard/ScriptTemplateWithArgs]
K2
[]
Property: class.metadata.contextReceiverTypes
K1
[]
K2
[kotlin/script/templates/standard/ScriptTemplateWithArgs]
PROPERTY getC()LKt48025$ReducedFraction;
Property: class.metadata.property.returnType
K1
Kt48025.ReducedFraction
K2
ReducedFraction
+1 -1
View File
@@ -1,4 +1,4 @@
// IGNORE_BACKEND_K2: JVM_IR
// JVM_ABI_K1_K2_DIFF: KT-63960, KT-63963, KT-63964
val p = 0
@@ -0,0 +1,30 @@
MODULE main
CLASS AnonymousObjectCapturesProperty.class
CLASS METADATA
K1
<init>([Ljava/lang/String;)V
K2
---
Property: class.metadata.superTypes
K1
[kotlin/script/templates/standard/ScriptTemplateWithArgs]
K2
[]
Property: class.metadata.contextReceiverTypes
K1
[]
K2
[kotlin/script/templates/standard/ScriptTemplateWithArgs]
PROPERTY getB()LAnonymousObjectCapturesProperty$A;
Property: class.metadata.property.returnType
K1
AnonymousObjectCapturesProperty.A
K2
A
CLASS AnonymousObjectCapturesProperty$B$1.class
CLASS METADATA
Property: class.metadata.superTypes
K1
[AnonymousObjectCapturesProperty.A]
K2
[A]
@@ -1,5 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND_K2: JVM_IR
// JVM_ABI_K1_K2_DIFF: KT-63960, KT-63963, KT-63964
// expected: rv: 42
@@ -0,0 +1,7 @@
// code from KT-64502
fun foo() {
bar()
}
fun bar() {}
@@ -0,0 +1,6 @@
fun foo() {
x
}
val x: Int get() = 42
@@ -25,6 +25,18 @@ public class ScriptWithCustomDefBlackBoxCodegenTestGenerated extends AbstractScr
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/scripting/scripting-tests/testData/codegen/testScripts"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("declarationsOrder1.test.kts")
public void testDeclarationsOrder1_test() {
runTest("plugins/scripting/scripting-tests/testData/codegen/testScripts/declarationsOrder1.test.kts");
}
@Test
@TestMetadata("declarationsOrder2.test.kts")
public void testDeclarationsOrder2_test() {
runTest("plugins/scripting/scripting-tests/testData/codegen/testScripts/declarationsOrder2.test.kts");
}
@Test
@TestMetadata("params.test.kts")
public void testParams_test() {