diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java index efaced7c563..76aa59c2aaf 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java @@ -145,12 +145,19 @@ public class SingleAbstractMethodUtils { CallableMemberDescriptor.Kind.SYNTHESIZED ); - JetType returnType = original.getReturnType(); + TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), result); + + JetType returnTypeUnsubstituted = original.getReturnType(); + assert returnTypeUnsubstituted != null : original; + JetType returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE); + assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor; List valueParameters = Lists.newArrayList(); for (ValueParameterDescriptor originalParam : original.getValueParameters()) { JetType originalType = originalParam.getType(); - JetType newType = isSamType(originalType) ? getFunctionTypeForSamType(originalType) : originalType; + JetType newTypeUnsubstituted = isSamType(originalType) ? getFunctionTypeForSamType(originalType) : originalType; + JetType newType = typeParameters.substitutor.substitute(newTypeUnsubstituted, Variance.IN_VARIANCE); + assert newType != null : "couldn't substitute type: " + newTypeUnsubstituted + ", substitutor = " + typeParameters.substitutor; ValueParameterDescriptor newParam = new ValueParameterDescriptorImpl( result, originalParam.getIndex(), originalParam.getAnnotations(), originalParam.getName(), newType, false, null); @@ -160,7 +167,7 @@ public class SingleAbstractMethodUtils { result.initialize( null, original.getExpectedThisObject(), - Collections.emptyList(), // TODO copy type parameters + typeParameters.descriptors, valueParameters, returnType, original.getModality(), diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfMethod.java b/compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfMethod.java new file mode 100644 index 00000000000..e9357e22d27 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfMethod.java @@ -0,0 +1,11 @@ +import java.util.*; + +class WeirdComparator { + public static T max(Comparator comparator, T value1, T value2) { + return comparator.compare(value1, value2) > 0 ? value1 : value2; + } + + public static T max2(Comparator comparator, T value1, T value2) { + return comparator.compare(value1, value2) > 0 ? value1 : value2; + } +} diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfMethod.kt b/compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfMethod.kt new file mode 100644 index 00000000000..fe0efd5053f --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfMethod.kt @@ -0,0 +1,9 @@ +fun box(): String { + val result = WeirdComparator.max({ a, b -> a.length - b.length }, "java", "kotlin") + if (result != "kotlin") return "Wrong: $result" + + val result2 = WeirdComparator.max2({ a, b -> a.length - b.length }, "java", "kotlin") + if (result2 != "kotlin") return "Wrong: $result" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfMethod.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfMethod.java new file mode 100644 index 00000000000..a6d3023cf93 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfMethod.java @@ -0,0 +1,19 @@ +package test; + +import java.lang.UnsupportedOperationException; +import java.util.*; +import java.util.Comparator; + +public class TypeParameterOfMethod { + public static T max(Comparator comparator, T value1, T value2) { + return comparator.compare(value1, value2) > 0 ? value1 : value2; + } + + public static T max2(Comparator comparator, T value1, T value2) { + return comparator.compare(value1, value2) > 0 ? value1 : value2; + } + + public static > void method(Comparator a, B b) { + throw new UnsupportedOperationException(); + } +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfMethod.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfMethod.txt new file mode 100644 index 00000000000..c53c07ca2dc --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfMethod.txt @@ -0,0 +1,14 @@ +package test + +public open class TypeParameterOfMethod : java.lang.Object { + public constructor TypeParameterOfMethod() +} + +package TypeParameterOfMethod { + public open /*synthesized*/ fun max(/*0*/ p0 : ((T?, T?) -> jet.Int)?, /*1*/ p1 : T?, /*2*/ p2 : T?) : T? + public open fun max(/*0*/ p0 : java.util.Comparator?, /*1*/ p1 : T?, /*2*/ p2 : T?) : T? + public open /*synthesized*/ fun max2(/*0*/ p0 : ((T?, T?) -> jet.Int)?, /*1*/ p1 : T?, /*2*/ p2 : T?) : T? + public open fun max2(/*0*/ p0 : java.util.Comparator?, /*1*/ p1 : T?, /*2*/ p2 : T?) : T? + public open /*synthesized*/ fun ?> method(/*0*/ p0 : ((A?, A?) -> jet.Int)?, /*1*/ p1 : B?) : jet.Unit + public open fun ?> method(/*0*/ p0 : java.util.Comparator?, /*1*/ p1 : B?) : jet.Unit +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index efde4beef36..9775f9207b3 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -142,6 +142,11 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfClass.kt"); } + @TestMetadata("typeParameterOfMethod.kt") + public void testTypeParameterOfMethod() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/typeParameterOfMethod.kt"); + } + } @TestMetadata("compiler/testData/codegen/boxWithJava/staticFun") diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 64beeb1fc1c..f43aa0dcf33 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -1244,6 +1244,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfClass.java"); } + @TestMetadata("TypeParameterOfMethod.java") + public void testTypeParameterOfMethod() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/TypeParameterOfMethod.java"); + } + } public static Test innerSuite() {