Do not generate properties for script parameters if there is template definition
This commit is contained in:
@@ -17,13 +17,18 @@
|
|||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
|
import kotlin.collections.CollectionsKt;
|
||||||
import kotlin.jvm.functions.Function0;
|
import kotlin.jvm.functions.Function0;
|
||||||
|
import kotlin.jvm.functions.Function1;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||||
import org.jetbrains.kotlin.codegen.context.ScriptContext;
|
import org.jetbrains.kotlin.codegen.context.ScriptContext;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ScriptDescriptor;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -148,8 +153,6 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
|||||||
|
|
||||||
ClassDescriptor superclass = DescriptorUtilsKt.getSuperClassNotAny(scriptDescriptor);
|
ClassDescriptor superclass = DescriptorUtilsKt.getSuperClassNotAny(scriptDescriptor);
|
||||||
|
|
||||||
List<ValueParameterDescriptor> valueParameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
|
|
||||||
|
|
||||||
if (superclass == null) {
|
if (superclass == null) {
|
||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
iv.invokespecial("java/lang/Object", "<init>", "()V", false);
|
iv.invokespecial("java/lang/Object", "<init>", "()V", false);
|
||||||
@@ -161,6 +164,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
|||||||
|
|
||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
|
|
||||||
|
List<ValueParameterDescriptor> valueParameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
|
||||||
for (Pair<Name, KotlinType> superclassParam: superclassParamsMap) {
|
for (Pair<Name, KotlinType> superclassParam: superclassParamsMap) {
|
||||||
ValueParameterDescriptor valueParam = null;
|
ValueParameterDescriptor valueParam = null;
|
||||||
for (ValueParameterDescriptor vpd: valueParameters) {
|
for (ValueParameterDescriptor vpd: valueParameters) {
|
||||||
@@ -190,11 +194,11 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes();
|
Type[] argTypes = jvmSignature.getAsmMethod().getArgumentTypes();
|
||||||
int add = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < valueParameters.size(); i++) {
|
List<ValueParameterDescriptor> parametersForProperties = getScriptParametersToUseAsProperties(scriptDescriptor);
|
||||||
ValueParameterDescriptor parameter = valueParameters.get(i);
|
for (int i = 0; i < parametersForProperties.size(); i++) {
|
||||||
frameMap.enter(parameter, argTypes[i + add]);
|
ValueParameterDescriptor parameter = parametersForProperties.get(i);
|
||||||
|
frameMap.enter(parameter, argTypes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int offset = 1;
|
int offset = 1;
|
||||||
@@ -207,7 +211,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
|||||||
iv.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
|
iv.putfield(classType.getInternalName(), context.getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
for (ValueParameterDescriptor parameter : parametersForProperties) {
|
||||||
Type parameterType = typeMapper.mapType(parameter.getType());
|
Type parameterType = typeMapper.mapType(parameter.getType());
|
||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
iv.load(offset, parameterType);
|
iv.load(offset, parameterType);
|
||||||
@@ -238,7 +242,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
|||||||
classBuilder.newField(NO_ORIGIN, access, context.getScriptFieldName(earlierScript), earlierClassName.getDescriptor(), null, null);
|
classBuilder.newField(NO_ORIGIN, access, context.getScriptFieldName(earlierScript), earlierClassName.getDescriptor(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : script.getUnsubstitutedPrimaryConstructor().getValueParameters()) {
|
for (ValueParameterDescriptor parameter : getScriptParametersToUseAsProperties(script)) {
|
||||||
Type parameterType = typeMapper.mapType(parameter);
|
Type parameterType = typeMapper.mapType(parameter);
|
||||||
int access = ACC_PUBLIC | ACC_FINAL;
|
int access = ACC_PUBLIC | ACC_FINAL;
|
||||||
classBuilder.newField(JvmDeclarationOriginKt.OtherOrigin(parameter), access, parameter.getName().getIdentifier(), parameterType.getDescriptor(), null, null);
|
classBuilder.newField(JvmDeclarationOriginKt.OtherOrigin(parameter), access, parameter.getName().getIdentifier(), parameterType.getDescriptor(), null, null);
|
||||||
@@ -255,4 +259,22 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<ValueParameterDescriptor> getScriptParametersToUseAsProperties(@NotNull ScriptDescriptor scriptDescriptor) {
|
||||||
|
List<ValueParameterDescriptor> parameters = scriptDescriptor.getUnsubstitutedPrimaryConstructor().getValueParameters();
|
||||||
|
final List<Pair<Name, KotlinType>> superclassParamsMap = scriptDescriptor.getScriptParametersToPassToSuperclass();
|
||||||
|
|
||||||
|
return CollectionsKt.filter(parameters, new Function1<ValueParameterDescriptor, Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean invoke(ValueParameterDescriptor descriptor) {
|
||||||
|
for (Pair<Name, KotlinType> superclassParam : superclassParamsMap) {
|
||||||
|
if (descriptor.getName().equals(superclassParam.getFirst())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -76,8 +76,9 @@ class LazyScriptClassMemberScope(
|
|||||||
|
|
||||||
override fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet<PropertyDescriptor>) {
|
override fun createPropertiesFromPrimaryConstructorParameters(name: Name, result: MutableSet<PropertyDescriptor>) {
|
||||||
val primaryConstructor = getPrimaryConstructor()!!
|
val primaryConstructor = getPrimaryConstructor()!!
|
||||||
|
val parametersToPassToSuperclass = scriptDescriptor.scriptParametersToPassToSuperclass.map { it.first }
|
||||||
for (valueParameterDescriptor in primaryConstructor.valueParameters) {
|
for (valueParameterDescriptor in primaryConstructor.valueParameters) {
|
||||||
if (name == valueParameterDescriptor.name) {
|
if (name == valueParameterDescriptor.name && name !in parametersToPassToSuperclass) {
|
||||||
result.add(createPropertyFromScriptParameter(scriptDescriptor, valueParameterDescriptor))
|
result.add(createPropertyFromScriptParameter(scriptDescriptor, valueParameterDescriptor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// this script expected parameter num: Int
|
||||||
|
|
||||||
|
val test = num + 10
|
||||||
|
System.out.println(test)
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
val num = 10 // check that we could declare property with the name as in the super class
|
||||||
|
System.out.println(num)
|
||||||
@@ -76,6 +76,20 @@ class ScriptTest2 {
|
|||||||
aClass!!.getConstructor(Integer.TYPE).newInstance(4)
|
aClass!!.getConstructor(Integer.TYPE).newInstance(4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScriptWithoutParams() {
|
||||||
|
val aClass = compileScript("without_params.kts", ScriptWithoutParams::class, null)
|
||||||
|
Assert.assertNotNull(aClass)
|
||||||
|
aClass!!.getConstructor(Integer.TYPE).newInstance(4)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScriptWithOverridenParam() {
|
||||||
|
val aClass = compileScript("overriden_parameter.kts", ScriptBaseClassWithOverridenProperty::class, null)
|
||||||
|
Assert.assertNotNull(aClass)
|
||||||
|
aClass!!.getConstructor(Integer.TYPE).newInstance(4)
|
||||||
|
}
|
||||||
|
|
||||||
private fun compileScript(
|
private fun compileScript(
|
||||||
scriptPath: String,
|
scriptPath: String,
|
||||||
scriptBase: KClass<out Any>,
|
scriptBase: KClass<out Any>,
|
||||||
@@ -167,17 +181,27 @@ class TestKotlinScriptDependenciesResolver : ScriptDependenciesResolver {
|
|||||||
@ScriptTemplateDefinition(
|
@ScriptTemplateDefinition(
|
||||||
scriptFilePattern =".*\\.kts",
|
scriptFilePattern =".*\\.kts",
|
||||||
resolver = TestKotlinScriptDependenciesResolver::class)
|
resolver = TestKotlinScriptDependenciesResolver::class)
|
||||||
abstract class ScriptWithIntParam(num: Int)
|
abstract class ScriptWithIntParam(val num: Int)
|
||||||
|
|
||||||
@ScriptTemplateDefinition(
|
@ScriptTemplateDefinition(
|
||||||
scriptFilePattern =".*\\.kts",
|
scriptFilePattern =".*\\.kts",
|
||||||
resolver = TestKotlinScriptDependenciesResolver::class)
|
resolver = TestKotlinScriptDependenciesResolver::class)
|
||||||
abstract class ScriptWithClassParam(param: TestParamClass)
|
abstract class ScriptWithClassParam(val param: TestParamClass)
|
||||||
|
|
||||||
@ScriptTemplateDefinition(
|
@ScriptTemplateDefinition(
|
||||||
scriptFilePattern =".*\\.kts",
|
scriptFilePattern =".*\\.kts",
|
||||||
resolver = TestKotlinScriptDependenciesResolver::class)
|
resolver = TestKotlinScriptDependenciesResolver::class)
|
||||||
abstract class ScriptWithBaseClass(num: Int, passthrough: Int) : TestDSLClassWithParam(passthrough)
|
abstract class ScriptWithBaseClass(val num: Int, passthrough: Int) : TestDSLClassWithParam(passthrough)
|
||||||
|
|
||||||
|
@ScriptTemplateDefinition(
|
||||||
|
scriptFilePattern =".*\\.kts",
|
||||||
|
resolver = TestKotlinScriptDependenciesResolver::class)
|
||||||
|
abstract class ScriptWithoutParams(num: Int)
|
||||||
|
|
||||||
|
@ScriptTemplateDefinition(
|
||||||
|
scriptFilePattern =".*\\.kts",
|
||||||
|
resolver = TestKotlinScriptDependenciesResolver::class)
|
||||||
|
abstract class ScriptBaseClassWithOverridenProperty(override val num: Int) : TestClassWithOverridableProperty(num)
|
||||||
|
|
||||||
@Target(AnnotationTarget.FILE)
|
@Target(AnnotationTarget.FILE)
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
|||||||
@@ -29,3 +29,5 @@ fun TestDSLInterface.fibCombine(f: (Int) -> Int, n: Int) = if (n < 2) 1 else f(n
|
|||||||
open class TestDSLClassWithParam(val offset: Int)
|
open class TestDSLClassWithParam(val offset: Int)
|
||||||
|
|
||||||
fun TestDSLClassWithParam.fibCombine(f: (Int) -> Int, n: Int) = if (n < 2) offset else f(n - 1) + f(n - 2)
|
fun TestDSLClassWithParam.fibCombine(f: (Int) -> Int, n: Int) = if (n < 2) offset else f(n - 1) + f(n - 2)
|
||||||
|
|
||||||
|
open class TestClassWithOverridableProperty(open val num: Int)
|
||||||
Reference in New Issue
Block a user