Skip to content

Commit ea33e72

Browse files
udalovSpace Team
authored andcommitted
JVM IR: script is a valid container for local delegated properties
When serializing metadata for local delegated properties, we need to find a valid container class where to put it, and where kotlin-reflect will be able to find that metadata at runtime. Taking just the closest class lexically doesn't work, because in the attached test, it is a class for a lambda which does not have metadata and thus does not have a way to store any extra information. So, in 1663619 we started to look for the closest "non-synthetic" class to store this metadata. But apparently it was missed that script is a valid container class. In the test, this meant that no non-synthetic container classes were found to store the metadata, so we falled back to using the closest class anyway (see `?: this` in `rememberLocalProperty`), which turned out to be the lambda. After this change, metadata for local delegated property in a lambda will be stored in the script class, just like it's stored in the file class in the non-script case. #KT-55065 Fixed (cherry picked from commit 3ab2b82)
1 parent c32cd10 commit ea33e72

File tree

5 files changed

+37
-7
lines changed

5 files changed

+37
-7
lines changed

compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : IrEle
202202

203203
val localProperties = mutableListOf<IrLocalDelegatedPropertySymbol>()
204204
val localPropertyIndices = mutableMapOf<IrSymbol, Int>()
205-
val isSynthetic = irClass.metadata !is MetadataSource.File && irClass.metadata !is MetadataSource.Class
205+
val isSynthetic = irClass.metadata !is MetadataSource.File && irClass.metadata !is MetadataSource.Class &&
206+
irClass.metadata !is MetadataSource.Script
206207

207208
fun localPropertyIndex(getter: IrSymbol): Int? =
208209
localPropertyIndices[getter] ?: parent?.localPropertyIndex(getter)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// WITH_REFLECT
2+
3+
import kotlin.reflect.KProperty
4+
5+
class Delegate {
6+
operator fun getValue(t: Any?, p: KProperty<*>): String =
7+
if (p.returnType.toString() == "kotlin.String") "OK" else "Fail: ${p.returnType}"
8+
}
9+
10+
fun f(lambda: () -> String): String = lambda()
11+
12+
val x = f {
13+
val prop: String by Delegate()
14+
prop
15+
}
16+
17+
// expected: x: OK

compiler/tests-common/tests/org/jetbrains/kotlin/codegen/AbstractScriptCodegenTest.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,23 @@
1717
package org.jetbrains.kotlin.codegen;
1818

1919
import com.intellij.openapi.util.Pair;
20+
import kotlin.io.FilesKt;
21+
import kotlin.text.Charsets;
2022
import org.jetbrains.annotations.NotNull;
2123
import org.jetbrains.kotlin.config.CompilerConfiguration;
2224
import org.jetbrains.kotlin.name.FqName;
2325
import org.jetbrains.kotlin.test.ConfigurationKind;
26+
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
2427
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
2528

2629
import java.io.File;
2730
import java.lang.reflect.Constructor;
2831
import java.lang.reflect.Field;
32+
import java.util.List;
2933

3034
import static org.jetbrains.kotlin.script.ScriptTestUtilKt.loadScriptingPlugin;
3135

3236
public abstract class AbstractScriptCodegenTest extends CodegenTestCase {
33-
@Override
34-
protected void setUp() throws Exception {
35-
super.setUp();
36-
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
37-
}
38-
3937
@Override
4038
protected void updateConfiguration(@NotNull CompilerConfiguration configuration) {
4139
super.updateConfiguration(configuration);
@@ -44,6 +42,10 @@ protected void updateConfiguration(@NotNull CompilerConfiguration configuration)
4442

4543
@Override
4644
protected void doTest(@NotNull String filename) {
45+
configurationKind = InTextDirectivesUtils.findLinesWithPrefixesRemoved(
46+
FilesKt.readText(new File(filename), Charsets.UTF_8), "// WITH_REFLECT"
47+
).isEmpty() ? ConfigurationKind.JDK_ONLY : ConfigurationKind.ALL;
48+
createEnvironmentWithMockJdkAndIdeaAnnotations(configurationKind);
4749
loadFileByFullPath(filename);
4850

4951
try {

compiler/tests-gen/org/jetbrains/kotlin/codegen/ScriptCodegenTestGenerated.java

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrScriptCodegenTestGenerated.java

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)