Fix provided properties access generation

The presense of accessors in the descriptor led to the wrong code
generation in some cases.
#KT-43176 fixed
This commit is contained in:
Ilya Chernikov
2020-12-10 15:36:40 +01:00
parent ffdcda8914
commit 1bd6cc823c
4 changed files with 48 additions and 57 deletions
@@ -0,0 +1,10 @@
// KOTLIN_SCRIPT_DEFINITION: org.jetbrains.kotlin.codegen.TestScriptWithSimpleEnvVars
// envVar: stringVar1=abracadabra
fun foo(body: () -> String): String = body()
val res = foo { stringVar1.drop(5) }
// expected: res=adabra
@@ -34,6 +34,11 @@ public class CustomScriptCodegenTestGenerated extends AbstractCustomScriptCodege
runTest("compiler/testData/codegen/customScript/pathPattern5.kts"); runTest("compiler/testData/codegen/customScript/pathPattern5.kts");
} }
@TestMetadata("providedPropsInLambda.kts")
public void testProvidedPropsInLambda_kts() throws Exception {
runTest("compiler/testData/codegen/customScript/providedPropsInLambda.kts");
}
@TestMetadata("simpleEnvVars.kts") @TestMetadata("simpleEnvVars.kts")
public void testSimpleEnvVars_kts() throws Exception { public void testSimpleEnvVars_kts() throws Exception {
runTest("compiler/testData/codegen/customScript/simpleEnvVars.kts"); runTest("compiler/testData/codegen/customScript/simpleEnvVars.kts");
@@ -18,6 +18,12 @@ private const val KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY = "kotlin.jsr2
@Suppress("unused") // accessed from the tests below @Suppress("unused") // accessed from the tests below
val shouldBeVisibleFromRepl = 7 val shouldBeVisibleFromRepl = 7
@Suppress("unused") // accessed from the tests below
fun callLambda(x: Int, aFunction: (Int) -> Int): Int = aFunction.invoke(x)
@Suppress("unused") // accessed from the tests below
inline fun inlineCallLambda(x: Int, aFunction: (Int) -> Int): Int = aFunction.invoke(x)
class KotlinJsr223ScriptEngineIT { class KotlinJsr223ScriptEngineIT {
init { init {
@@ -297,6 +303,30 @@ obj
Assert.assertEquals(42, result) Assert.assertEquals(42, result)
} }
@Test
fun testResolveFromContextLambda() {
val scriptEngine = ScriptEngineManager().getEngineByExtension("kts")!!
val script1 = """
kotlin.script.experimental.jsr223.test.callLambda(4) { x ->
x % aValue
}
"""
val script2 = """
kotlin.script.experimental.jsr223.test.inlineCallLambda(5) { x ->
x % aValue
}
"""
scriptEngine.put("aValue", 3)
val res1 = scriptEngine.eval(script1)
Assert.assertEquals(1, res1)
val res2 = scriptEngine.eval(script2)
Assert.assertEquals(2, res2)
}
@Test @Test
fun testResolveFromContextDirectExperimental() { fun testResolveFromContextDirectExperimental() {
val prevProp = System.setProperty(KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY, "true") val prevProp = System.setProperty(KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY, "true")
@@ -8,9 +8,6 @@ package org.jetbrains.kotlin.scripting.resolve
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class ScriptProvidedPropertyDescriptor( class ScriptProvidedPropertyDescriptor(
@@ -24,7 +21,7 @@ class ScriptProvidedPropertyDescriptor(
null, null,
Annotations.EMPTY, Annotations.EMPTY,
Modality.FINAL, Modality.FINAL,
DescriptorVisibilities.PRIVATE, DescriptorVisibilities.PUBLIC,
isVar, isVar,
name, name,
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
@@ -34,58 +31,7 @@ class ScriptProvidedPropertyDescriptor(
) { ) {
init { init {
setType(typeDescriptor.defaultType, emptyList(), receiver, null) setType(typeDescriptor.defaultType, emptyList(), receiver, null)
initialize( // TODO: consider delegation instead
makePropertyGetterDescriptor(), initialize(null, null, null, null)
if (!isVar) null else makePropertySetterDescriptor()
)
} }
} }
private fun PropertyDescriptorImpl.makePropertyGetterDescriptor() =
PropertyGetterDescriptorImpl(
this,
Annotations.EMPTY,
this.modality,
this.visibility,
/* isDefault = */
false, /* isExternal = */
false, /* isInline = */
false,
this.kind,
null,
SourceElement.NO_SOURCE
).also {
it.initialize(returnType)
}
private fun PropertyDescriptorImpl.makePropertySetterDescriptor() =
PropertySetterDescriptorImpl(
this,
Annotations.EMPTY,
this.modality,
this.visibility,
/* isDefault = */
false, /* isExternal = */
false, /* isInline = */
false,
this.kind,
null,
SourceElement.NO_SOURCE
).also {
it.initialize(
ValueParameterDescriptorImpl(
this,
null,
0,
Annotations.EMPTY,
Name.special("<set-?>"),
returnType,
/* declaresDefaultValue = */
false, /* isCrossinline = */
false, /* isNoinline = */
false,
null,
SourceElement.NO_SOURCE
)
)
}