Loading functional interfaces with generic parameters.
This commit is contained in:
+1
-1
@@ -34,7 +34,7 @@ public class SignaturesUtil {
|
|||||||
@NotNull List<TypeParameterDescriptor> originalParameters,
|
@NotNull List<TypeParameterDescriptor> originalParameters,
|
||||||
@Nullable DeclarationDescriptor newOwner
|
@Nullable DeclarationDescriptor newOwner
|
||||||
) {
|
) {
|
||||||
Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> result = Maps.newHashMap();
|
Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> result = Maps.newLinkedHashMap(); // save order of type parameters
|
||||||
for (TypeParameterDescriptor typeParameter : originalParameters) {
|
for (TypeParameterDescriptor typeParameter : originalParameters) {
|
||||||
result.put(typeParameter,
|
result.put(typeParameter,
|
||||||
TypeParameterDescriptorImpl.createForFurtherModification(
|
TypeParameterDescriptorImpl.createForFurtherModification(
|
||||||
|
|||||||
+24
-4
@@ -21,14 +21,19 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
|
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class SingleAbstractMethodUtils {
|
public class SingleAbstractMethodUtils {
|
||||||
public static boolean isFunctionalInterface(@NotNull ClassDescriptor klass) {
|
public static boolean isFunctionalInterface(@NotNull ClassDescriptor klass) {
|
||||||
@@ -53,7 +58,6 @@ public class SingleAbstractMethodUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static JetType getFunctionalTypeForFunction(@NotNull FunctionDescriptor function) {
|
private static JetType getFunctionalTypeForFunction(@NotNull FunctionDescriptor function) {
|
||||||
// TODO substitute type parameters of class
|
|
||||||
// TODO substitute type parameters of function with star projections
|
// TODO substitute type parameters of function with star projections
|
||||||
JetType returnType = function.getReturnType();
|
JetType returnType = function.getReturnType();
|
||||||
assert returnType != null : "function is not initialized: " + function;
|
assert returnType != null : "function is not initialized: " + function;
|
||||||
@@ -72,16 +76,32 @@ public class SingleAbstractMethodUtils {
|
|||||||
CallableMemberDescriptor.Kind.SYNTHESIZED
|
CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||||
);
|
);
|
||||||
|
|
||||||
JetType parameterType = getFunctionalTypeForFunction(getAbstractMethodOfFunctionalInterface(klass));;
|
Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> traitToFunTypeParameters =
|
||||||
|
SignaturesUtil.recreateTypeParametersAndReturnMapping(klass.getTypeConstructor().getParameters(), result);
|
||||||
|
TypeSubstitutor typeParametersSubstitutor = SignaturesUtil.createSubstitutorForTypeParameters(traitToFunTypeParameters);
|
||||||
|
|
||||||
|
JetType parameterTypeUnsubstituted = getFunctionalTypeForFunction(getAbstractMethodOfFunctionalInterface(klass));
|
||||||
|
JetType parameterType = typeParametersSubstitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE);
|
||||||
|
assert parameterType != null : "couldn't substitute type: " + parameterType + ", substitutor = " + typeParametersSubstitutor;
|
||||||
ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl(
|
ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl(
|
||||||
result, 0, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("function"), parameterType, false, null);
|
result, 0, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("function"), parameterType, false, null);
|
||||||
|
|
||||||
|
JetType returnType = typeParametersSubstitutor.substitute(klass.getDefaultType(), Variance.OUT_VARIANCE);
|
||||||
|
assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParametersSubstitutor;
|
||||||
|
|
||||||
|
for (TypeParameterDescriptorImpl typeParameter : traitToFunTypeParameters.values()) {
|
||||||
|
// TODO copy substituted upper bound
|
||||||
|
// TODO consider recursive upper bound
|
||||||
|
typeParameter.addDefaultUpperBound();
|
||||||
|
typeParameter.setInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
result.initialize(
|
result.initialize(
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
Lists.<TypeParameterDescriptor>newArrayList(), // TODO recreate type parameters of class
|
Lists.newArrayList(traitToFunTypeParameters.values()),
|
||||||
Arrays.asList(parameter),
|
Arrays.asList(parameter),
|
||||||
klass.getDefaultType(), // TODO substitute type parameters of class
|
returnType,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
klass.getVisibility(),
|
klass.getVisibility(),
|
||||||
false
|
false
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
public interface Comparator<T> {
|
||||||
|
int compare(T o1, T o2);
|
||||||
|
|
||||||
|
boolean equals(Object obj);
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public /*synthesized*/ fun </*0*/ T> Comparator(/*0*/ function : (T?, T?) -> jet.Int) : test.Comparator<T>
|
||||||
|
|
||||||
|
public trait Comparator</*0*/ T> : java.lang.Object {
|
||||||
|
public abstract fun compare(/*0*/ p0 : T?, /*1*/ p1 : T?) : jet.Int
|
||||||
|
}
|
||||||
@@ -1130,6 +1130,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/compiledJava/singleAbstractMethod"), Pattern.compile("^(.+)\\.java$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/compiledJava/singleAbstractMethod"), Pattern.compile("^(.+)\\.java$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Comparator.java")
|
||||||
|
public void testComparator() throws Exception {
|
||||||
|
doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/Comparator.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("FilenameFilter.java")
|
@TestMetadata("FilenameFilter.java")
|
||||||
public void testFilenameFilter() throws Exception {
|
public void testFilenameFilter() throws Exception {
|
||||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/FilenameFilter.java");
|
doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/FilenameFilter.java");
|
||||||
|
|||||||
Reference in New Issue
Block a user