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");
}
@TestMetadata("providedPropsInLambda.kts")
public void testProvidedPropsInLambda_kts() throws Exception {
runTest("compiler/testData/codegen/customScript/providedPropsInLambda.kts");
}
@TestMetadata("simpleEnvVars.kts")
public void testSimpleEnvVars_kts() throws Exception {
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
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 {
init {
@@ -297,6 +303,30 @@ obj
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
fun testResolveFromContextDirectExperimental() {
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.annotations.Annotations
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
class ScriptProvidedPropertyDescriptor(
@@ -24,7 +21,7 @@ class ScriptProvidedPropertyDescriptor(
null,
Annotations.EMPTY,
Modality.FINAL,
DescriptorVisibilities.PRIVATE,
DescriptorVisibilities.PUBLIC,
isVar,
name,
CallableMemberDescriptor.Kind.SYNTHESIZED,
@@ -34,58 +31,7 @@ class ScriptProvidedPropertyDescriptor(
) {
init {
setType(typeDescriptor.defaultType, emptyList(), receiver, null)
initialize(
makePropertyGetterDescriptor(),
if (!isVar) null else makePropertySetterDescriptor()
)
// TODO: consider delegation instead
initialize(null, null, null, null)
}
}
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
)
)
}