Copy type parameters for JVM function accessors

Otherwise generic signature wasn't correctly written to accessors, resulting in
classfiles not being valid and javac failing to compile Java sources against
them
This commit is contained in:
Alexander Udalov
2014-02-26 21:09:48 +04:00
parent fbdba0f48d
commit 8425f2e668
4 changed files with 47 additions and 2 deletions
@@ -20,11 +20,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
@@ -41,13 +42,31 @@ public class AccessorForFunctionDescriptor extends SimpleFunctionDescriptorImpl
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getReceiverParameter()),
descriptor instanceof ConstructorDescriptor ? NO_RECEIVER_PARAMETER : descriptor.getExpectedThisObject(),
Collections.<TypeParameterDescriptor>emptyList(),
copyTypeParameters(descriptor),
copyValueParameters(descriptor),
descriptor.getReturnType(),
Modality.FINAL,
Visibilities.INTERNAL);
}
@NotNull
private List<TypeParameterDescriptor> copyTypeParameters(@NotNull FunctionDescriptor descriptor) {
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeParameters();
List<TypeParameterDescriptor> result = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
for (TypeParameterDescriptor typeParameter : typeParameters) {
TypeParameterDescriptorImpl copy = TypeParameterDescriptorImpl.createForFurtherModification(
this, typeParameter.getAnnotations(), typeParameter.isReified(),
typeParameter.getVariance(), typeParameter.getName(), typeParameter.getIndex()
);
for (JetType upperBound : typeParameter.getUpperBounds()) {
copy.addUpperBound(upperBound);
}
copy.setInitialized();
result.add(copy);
}
return result;
}
@NotNull
private List<ValueParameterDescriptor> copyValueParameters(@NotNull FunctionDescriptor descriptor) {
List<ValueParameterDescriptor> valueParameters = descriptor.getValueParameters();
@@ -0,0 +1,5 @@
package test;
public class AccessorGenericSignature {
private final BadClass b = new BadClass();
}
@@ -0,0 +1,16 @@
package test
import java.util.ArrayList
public class BadClass {
fun foo() {
val x: () -> Int = {
bar(ArrayList<Int>())
baz<Double, ArrayList<ArrayList>>(ArrayList())
}
}
private fun <D> bar(f: List<D>) {}
private fun <E : Number, F : MutableList<E>> baz(m: List<F>) {}
}
@@ -93,6 +93,11 @@ public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAg
@TestMetadata("compiler/testData/compileJavaAgainstKotlin/method")
@InnerTestClasses({Method.PrimitiveOverride.class, Method.Throws.class})
public static class Method extends AbstractCompileJavaAgainstKotlinTest {
@TestMetadata("AccessorGenericSignature.kt")
public void testAccessorGenericSignature() throws Exception {
doTest("compiler/testData/compileJavaAgainstKotlin/method/AccessorGenericSignature.kt");
}
public void testAllFilesPresentInMethod() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/compileJavaAgainstKotlin/method"), Pattern.compile("^(.+)\\.kt$"), true);
}