diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java index 3d311a7dc06..924c8f87f20 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/AlternativeMethodSignatureData.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java.kotlinSignature; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiNamedElement; import com.intellij.util.containers.ComparatorUtil; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; @@ -37,9 +38,7 @@ import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT; import static org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage.UPPER_BOUND; @@ -232,41 +231,35 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD TypeParameterDescriptorImpl altParamDescriptor = originalToAltTypeParameters.get(originalTypeParamDescriptor); JetTypeParameter altTypeParameter = altFunDeclaration.getTypeParameters().get(i); - int upperBoundIndex = 0; - for (JetType upperBound : originalTypeParamDescriptor.getUpperBounds()) { - JetTypeElement altTypeElement; - - if (upperBoundIndex == 0) { - JetTypeReference extendsBound = altTypeParameter.getExtendsBound(); - if (extendsBound == null) { // default upper bound - assert originalTypeParamDescriptor.getUpperBounds().size() == 1; - altParamDescriptor.addDefaultUpperBound(); - break; - } - else { - altTypeElement = extendsBound.getTypeElement(); - } + Set originalUpperBounds = originalTypeParamDescriptor.getUpperBounds(); + List altUpperBounds = getUpperBounds(altFunDeclaration, altTypeParameter); + if (altUpperBounds.size() != originalUpperBounds.size()) { + if (altUpperBounds.isEmpty() + && originalUpperBounds.equals(Collections.singleton(KotlinBuiltIns.getInstance().getDefaultBound()))) { + // Only default bound => no error } else { - JetTypeConstraint constraint = - findTypeParameterConstraint(altFunDeclaration, originalTypeParamDescriptor.getName(), upperBoundIndex); - if (constraint == null) { - throw new AlternativeSignatureMismatchException("Upper bound #%d for type parameter %s is missing", - upperBoundIndex, originalTypeParamDescriptor.getName()); - } - //noinspection ConstantConditions - altTypeElement = constraint.getBoundTypeReference().getTypeElement(); + throw new AlternativeSignatureMismatchException("Upper bound number mismatch for %s. Expected %d, but found %d", + originalTypeParamDescriptor.getName(), + originalUpperBounds.size(), + altUpperBounds.size()); } - - assert (altTypeElement != null); - - altParamDescriptor.addUpperBound(TypeTransformingVisitor.computeType(altTypeElement, upperBound, - originalToAltTypeParameters, UPPER_BOUND)); - upperBoundIndex++; } - if (findTypeParameterConstraint(altFunDeclaration, originalTypeParamDescriptor.getName(), upperBoundIndex) != null) { - throw new AlternativeSignatureMismatchException("Extra upper bound #%d for type parameter %s", upperBoundIndex, originalTypeParamDescriptor.getName()); + if (altUpperBounds.isEmpty()) { + altParamDescriptor.addDefaultUpperBound(); + } + else { + int upperBoundIndex = 0; + for (JetType upperBound : originalUpperBounds) { + + JetTypeElement altTypeElement = altUpperBounds.get(upperBoundIndex).getTypeElement(); + assert altTypeElement != null; + + altParamDescriptor.addUpperBound(TypeTransformingVisitor.computeType(altTypeElement, upperBound, + originalToAltTypeParameters, UPPER_BOUND)); + upperBoundIndex++; + } } altParamDescriptor.setInitialized(); @@ -274,22 +267,23 @@ public class AlternativeMethodSignatureData extends ElementAlternativeSignatureD } } - @Nullable - private static JetTypeConstraint findTypeParameterConstraint(@NotNull JetFunction function, @NotNull Name typeParameterName, int index) { - if (index != 0) { - int currentIndex = 0; - for (JetTypeConstraint constraint : function.getTypeConstraints()) { - JetSimpleNameExpression parameterName = constraint.getSubjectTypeParameterName(); - assert parameterName != null; - if (typeParameterName.equals(parameterName.getReferencedNameAsName())) { - currentIndex++; - } - if (currentIndex == index) { - return constraint; - } + @NotNull + private static List getUpperBounds(@NotNull JetFunction function, @NotNull JetTypeParameter jetTypeParameter) { + List result = new ArrayList(); + ContainerUtil.addIfNotNull(result, jetTypeParameter.getExtendsBound()); + + Name name = jetTypeParameter.getNameAsName(); + if (name == null) return result; + + for (JetTypeConstraint constraint : function.getTypeConstraints()) { + JetSimpleNameExpression parameterName = constraint.getSubjectTypeParameterName(); + assert parameterName != null : "No parameter name in constraint " + constraint.getText(); + if (name.equals(parameterName.getReferencedNameAsName())) { + result.add(constraint.getBoundTypeReference()); } } - return null; + + return result; } private static void checkEqualFunctionNames(@NotNull PsiNamedElement namedElement, @NotNull JavaMethod method) { diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.java b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.java new file mode 100644 index 00000000000..88cfaf6dc94 --- /dev/null +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.java @@ -0,0 +1,12 @@ +package test; + +import jet.runtime.typeinfo.KotlinSignature; + +import java.io.Serializable; + +public class AllBoundsInWhen { + @KotlinSignature("fun foo() where T: Serializable") + public void foo() { + throw new UnsupportedOperationException(); + } +} diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.kt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.kt new file mode 100644 index 00000000000..ed3f2f39049 --- /dev/null +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.kt @@ -0,0 +1,9 @@ +package test + +import java.io.Serializable + +public open class AllBoundsInWhen : Object() { + public open fun foo() where T: Serializable { + throw UnsupportedOperationException() + } +} diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.txt b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.txt new file mode 100644 index 00000000000..07d3750d448 --- /dev/null +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.txt @@ -0,0 +1,6 @@ +package test + +public open class AllBoundsInWhen : java.lang.Object { + public constructor AllBoundsInWhen() + public open fun foo(): kotlin.Unit +} diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/ExtraUpperBound.java b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/ExtraUpperBound.java index e059a422aac..74f47f07ed5 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/ExtraUpperBound.java +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/ExtraUpperBound.java @@ -4,7 +4,7 @@ import jet.runtime.typeinfo.KotlinSignature; import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError; public class ExtraUpperBound { - @ExpectLoadError("Extra upper bound #1 for type parameter A") + @ExpectLoadError("Upper bound number mismatch for A. Expected 1, but found 2") @KotlinSignature("fun foo() : String where A : Cloneable") public String foo() { throw new UnsupportedOperationException(); diff --git a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.java b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.java index e95bdc028e9..97aa577cbbe 100644 --- a/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.java +++ b/compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/error/MissingUpperBound.java @@ -4,7 +4,7 @@ import jet.runtime.typeinfo.KotlinSignature; import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError; public class MissingUpperBound { - @ExpectLoadError("Upper bound #1 for type parameter A is missing") + @ExpectLoadError("Upper bound number mismatch for A. Expected 2, but found 1") @KotlinSignature("fun foo() : String") public String foo() { throw new UnsupportedOperationException(); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 21cffd3d788..4f28b2e3dbe 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -778,6 +778,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { @TestMetadata("compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature") @InnerTestClasses({KotlinSignature.Error.class, KotlinSignature.Propagation.class}) public static class KotlinSignature extends AbstractLoadJavaTest { + @TestMetadata("AllBoundsInWhen.java") + public void testAllBoundsInWhen() throws Exception { + doTestCompiledJavaCompareWithKotlin("compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.java"); + } + public void testAllFilesPresentInKotlinSignature() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature"), Pattern.compile("^(.+)\\.java$"), true); } diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java index ee301bf5481..c7b75b0fffe 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java @@ -1736,6 +1736,11 @@ public class LazyResolveRecursiveComparingTestGenerated extends AbstractLazyReso @TestMetadata("compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature") @InnerTestClasses({KotlinSignature.Error.class, KotlinSignature.Propagation.class}) public static class KotlinSignature extends AbstractLazyResolveRecursiveComparingTest { + @TestMetadata("AllBoundsInWhen.kt") + public void testAllBoundsInWhen() throws Exception { + doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature/AllBoundsInWhen.kt"); + } + public void testAllFilesPresentInKotlinSignature() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/loadJava/compiledJavaCompareWithKotlin/kotlinSignature"), Pattern.compile("^(.+)\\.kt$"), true); }