diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java index 84d27fb1d12..bdbaf195bb0 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java @@ -25,7 +25,10 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.java.*; +import org.jetbrains.jet.lang.resolve.java.JavaToKotlinClassMap; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.KotlinToJavaTypesMap; +import org.jetbrains.jet.lang.resolve.java.TypeUsage; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -33,7 +36,8 @@ import org.jetbrains.jet.renderer.DescriptorRenderer; import java.util.*; -import static org.jetbrains.jet.lang.resolve.java.TypeUsage.*; +import static org.jetbrains.jet.lang.resolve.java.TypeUsage.TYPE_ARGUMENT; +import static org.jetbrains.jet.lang.types.Variance.INVARIANT; class TypeTransformingVisitor extends JetVisitor { private final JetType originalType; @@ -113,6 +117,18 @@ class TypeTransformingVisitor extends JetVisitor { throw new AlternativeSignatureMismatchException("Alternative signature type mismatch, expected: %s, actual: %s", qualifiedName, fqName); } + TypeConstructor typeConstructor; + if (classFromLibrary != null) { + typeConstructor = classFromLibrary.getTypeConstructor(); + } + else { + typeConstructor = originalTypeConstructor; + } + ClassifierDescriptor typeConstructorClassifier = typeConstructor.getDeclarationDescriptor(); + if (typeConstructorClassifier instanceof TypeParameterDescriptor && originalToAltTypeParameters.containsKey(typeConstructorClassifier)) { + typeConstructor = originalToAltTypeParameters.get(typeConstructorClassifier).getTypeConstructor(); + } + List arguments = originalType.getArguments(); if (arguments.size() != type.getTypeArgumentsAsTypes().size()) { @@ -138,6 +154,7 @@ class TypeTransformingVisitor extends JetVisitor { JetTypeElement argumentAlternativeTypeElement = typeReference.getTypeElement(); assert argumentAlternativeTypeElement != null; + TypeParameterDescriptor parameter = typeConstructor.getParameters().get(i); TypeProjection argument = arguments.get(i); JetType alternativeArgumentType = computeType(argumentAlternativeTypeElement, argument.getType(), originalToAltTypeParameters, TYPE_ARGUMENT); Variance projectionKind = argument.getProjectionKind(); @@ -160,6 +177,16 @@ class TypeTransformingVisitor extends JetVisitor { throw new AlternativeSignatureMismatchException("Projection kind mismatch, actual: %s, in alternative signature: %s", projectionKind, altProjectionKind); } + if (altProjectionKind != INVARIANT && parameter.getVariance() != INVARIANT) { + if (altProjectionKind == parameter.getVariance()) { + // TODO report redundant if in strict mode + } + else { + throw new AlternativeSignatureMismatchException("Projection kind '%s' is conflicting with variance of %s", + altProjectionKind, DescriptorUtils.getFQName(typeConstructor.getDeclarationDescriptor())); + } + altProjectionKind = projectionKind; + } } else { altProjectionKind = projectionKind; @@ -167,17 +194,6 @@ class TypeTransformingVisitor extends JetVisitor { altArguments.add(new TypeProjection(altProjectionKind, alternativeArgumentType)); } - TypeConstructor typeConstructor; - if (classFromLibrary != null) { - typeConstructor = classFromLibrary.getTypeConstructor(); - } - else { - typeConstructor = originalTypeConstructor; - } - ClassifierDescriptor typeConstructorClassifier = typeConstructor.getDeclarationDescriptor(); - if (typeConstructorClassifier instanceof TypeParameterDescriptor && originalToAltTypeParameters.containsKey(typeConstructorClassifier)) { - typeConstructor = originalToAltTypeParameters.get(typeConstructorClassifier).getTypeConstructor(); - } JetScope memberScope; if (typeConstructorClassifier instanceof TypeParameterDescriptor) { memberScope = ((TypeParameterDescriptor) typeConstructorClassifier).getUpperBoundsAsType().getMemberScope(); diff --git a/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.java b/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.java index a243e3e199e..a549d970280 100644 --- a/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.java +++ b/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.java @@ -5,8 +5,8 @@ import java.util.*; import jet.runtime.typeinfo.KotlinSignature; public class MethodWithMappedClasses { - @KotlinSignature("fun copy(dest : MutableList, src : List)") - public void copy(List dest, List src) { + @KotlinSignature("fun copy(dest : MutableList, src : List)") + public void copy(List dest, List src) { throw new UnsupportedOperationException(); } } diff --git a/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.kt b/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.kt index 4de303b8576..463d7420c17 100644 --- a/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.kt +++ b/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.kt @@ -3,5 +3,5 @@ package test import java.util.* public open class MethodWithMappedClasses : Object() { - public open fun copy(p0 : MutableList, p1 : List) {} + public open fun copy(p0 : MutableList, p1 : List) {} } diff --git a/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.txt b/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.txt index a60e542edf7..637c5dfdaa9 100644 --- a/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.txt +++ b/compiler/testData/loadJava/kotlinSignature/MethodWithMappedClasses.txt @@ -2,5 +2,5 @@ package test public open class MethodWithMappedClasses : java.lang.Object { public constructor MethodWithMappedClasses() - public open fun copy(/*0*/ p0 : jet.MutableList, /*1*/ p1 : jet.List) : Unit + public open fun copy(/*0*/ p0 : jet.MutableList, /*1*/ p1 : jet.List) : Unit } diff --git a/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.java b/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.java index 11515052502..62d65ed7375 100644 --- a/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.java +++ b/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.java @@ -8,7 +8,7 @@ import java.util.List; import jet.runtime.typeinfo.KotlinSignature; public class MethodWithTypeParameters { - @KotlinSignature("fun foo(a : A, b : List, c: MutableList) where B : List") + @KotlinSignature("fun foo(a : A, b : List, c: MutableList) where B : List") public > void foo(A a, List b, List list) { } } diff --git a/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.kt b/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.kt index f83804504fd..d9a00220f50 100644 --- a/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.kt +++ b/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.kt @@ -3,6 +3,6 @@ package test import java.util.* public open class MethodWithTypeParameters : Object() { - public open fun foo(p0 : A, p1 : List, p2: MutableList) where B : List { + public open fun foo(p0 : A, p1 : List, p2: MutableList) where B : List { } } diff --git a/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.txt b/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.txt index 97184b5de92..c84e685ad5b 100644 --- a/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.txt +++ b/compiler/testData/loadJava/kotlinSignature/MethodWithTypeParameters.txt @@ -2,5 +2,5 @@ package test public open class MethodWithTypeParameters : java.lang.Object { public constructor MethodWithTypeParameters() - public open fun foo(/*0*/ p0 : A, /*1*/ p1 : jet.List, /*2*/ p2 : jet.MutableList) : Unit where B : java.lang.Runnable, B : jet.List + public open fun foo(/*0*/ p0 : A, /*1*/ p1 : jet.List, /*2*/ p2 : jet.MutableList) : Unit where B : java.lang.Runnable, B : jet.List } diff --git a/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.java b/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.java new file mode 100644 index 00000000000..503121326e0 --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.java @@ -0,0 +1,15 @@ +package test; + +import java.lang.Number; +import java.util.*; + +import jet.runtime.typeinfo.KotlinSignature; +import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError; + +public class ConflictingProjectionKind { + @ExpectLoadError("Projection kind 'in' is conflicting with variance of jet.List") + @KotlinSignature("fun foo(list: List)") + public void foo(List list) { + throw new UnsupportedOperationException(); + } +} diff --git a/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.kt b/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.kt new file mode 100644 index 00000000000..b9fbbcd766b --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.kt @@ -0,0 +1,7 @@ +package test + +public open class ConflictingProjectionKind : Object() { + public open fun foo(p0: List?) { + throw UnsupportedOperationException() + } +} diff --git a/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.txt b/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.txt new file mode 100644 index 00000000000..a7e2f429fc1 --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.txt @@ -0,0 +1,6 @@ +package test + +public open class ConflictingProjectionKind : java.lang.Object { + public constructor ConflictingProjectionKind() + public open fun foo(/*0*/ p0 : jet.List?) : Unit +} diff --git a/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.java b/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.java new file mode 100644 index 00000000000..d1695f6ba02 --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.java @@ -0,0 +1,14 @@ +package test; + +import java.lang.Number; +import java.util.*; + +import jet.runtime.typeinfo.KotlinSignature; +import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError; + +public class RedundantProjectionKind { + @KotlinSignature("fun foo(list: List)") + public void foo(List list) { + throw new UnsupportedOperationException(); + } +} diff --git a/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.kt b/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.kt new file mode 100644 index 00000000000..b241e86d29b --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.kt @@ -0,0 +1,7 @@ +package test + +public open class RedundantProjectionKind : Object() { + public open fun foo(p0: List) { + throw UnsupportedOperationException() + } +} diff --git a/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.txt b/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.txt new file mode 100644 index 00000000000..3cf7a00a492 --- /dev/null +++ b/compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.txt @@ -0,0 +1,6 @@ +package test + +public open class RedundantProjectionKind : java.lang.Object { + public constructor RedundantProjectionKind() + public open fun foo(/*0*/ p0 : jet.List) : Unit +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 5a6df8345c9..4861745c39c 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -343,6 +343,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/kotlinSignature/error"), "java", true); } + @TestMetadata("ConflictingProjectionKind.java") + public void testConflictingProjectionKind() throws Exception { + doTest("compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.java"); + } + @TestMetadata("ExplicitFieldGettersAndSetters.java") public void testExplicitFieldGettersAndSetters() throws Exception { doTest("compiler/testData/loadJava/kotlinSignature/error/ExplicitFieldGettersAndSetters.java"); @@ -368,6 +373,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTest("compiler/testData/loadJava/kotlinSignature/error/NotVarargReplacedWithVararg.java"); } + @TestMetadata("RedundantProjectionKind.java") + public void testRedundantProjectionKind() throws Exception { + doTest("compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.java"); + } + @TestMetadata("ReturnTypeMissing.java") public void testReturnTypeMissing() throws Exception { doTest("compiler/testData/loadJava/kotlinSignature/error/ReturnTypeMissing.java"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index d828335ef85..d1bbb8b546e 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -1312,6 +1312,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/kotlinSignature/error"), "kt", true); } + @TestMetadata("ConflictingProjectionKind.kt") + public void testConflictingProjectionKind() throws Exception { + doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/kotlinSignature/error/ConflictingProjectionKind.kt"); + } + @TestMetadata("ExplicitFieldGettersAndSetters.kt") public void testExplicitFieldGettersAndSetters() throws Exception { doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/kotlinSignature/error/ExplicitFieldGettersAndSetters.kt"); @@ -1337,6 +1342,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/kotlinSignature/error/NotVarargReplacedWithVararg.kt"); } + @TestMetadata("RedundantProjectionKind.kt") + public void testRedundantProjectionKind() throws Exception { + doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/kotlinSignature/error/RedundantProjectionKind.kt"); + } + @TestMetadata("ReturnTypeMissing.kt") public void testReturnTypeMissing() throws Exception { doTestNotCheckingPrimaryConstructors("compiler/testData/loadJava/kotlinSignature/error/ReturnTypeMissing.kt");