Checking redundant/conflicting projection kind in alt signatures.
This commit is contained in:
+29
-13
@@ -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<JetType, Void> {
|
||||
private final JetType originalType;
|
||||
@@ -113,6 +117,18 @@ class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
|
||||
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<TypeProjection> arguments = originalType.getArguments();
|
||||
|
||||
if (arguments.size() != type.getTypeArgumentsAsTypes().size()) {
|
||||
@@ -138,6 +154,7 @@ class TypeTransformingVisitor extends JetVisitor<JetType, Void> {
|
||||
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<JetType, Void> {
|
||||
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<JetType, Void> {
|
||||
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();
|
||||
|
||||
@@ -5,8 +5,8 @@ import java.util.*;
|
||||
import jet.runtime.typeinfo.KotlinSignature;
|
||||
|
||||
public class MethodWithMappedClasses {
|
||||
@KotlinSignature("fun <T> copy(dest : MutableList<in T>, src : List<out T>)")
|
||||
public <T> void copy(List<? super T> dest, List<? extends T> src) {
|
||||
@KotlinSignature("fun <T> copy(dest : MutableList<in T>, src : List<T>)")
|
||||
public <T> void copy(List<? super T> dest, List<T> src) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ package test
|
||||
import java.util.*
|
||||
|
||||
public open class MethodWithMappedClasses : Object() {
|
||||
public open fun <T> copy(p0 : MutableList<in T>, p1 : List<out T>) {}
|
||||
public open fun <T> copy(p0 : MutableList<in T>, p1 : List<T>) {}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ package test
|
||||
|
||||
public open class MethodWithMappedClasses : java.lang.Object {
|
||||
public constructor MethodWithMappedClasses()
|
||||
public open fun </*0*/ T> copy(/*0*/ p0 : jet.MutableList<in T>, /*1*/ p1 : jet.List<out T>) : Unit
|
||||
public open fun </*0*/ T> copy(/*0*/ p0 : jet.MutableList<in T>, /*1*/ p1 : jet.List<T>) : Unit
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
import jet.runtime.typeinfo.KotlinSignature;
|
||||
|
||||
public class MethodWithTypeParameters {
|
||||
@KotlinSignature("fun <A, B : Runnable> foo(a : A, b : List<out B>, c: MutableList<in String?>) where B : List<Cloneable>")
|
||||
@KotlinSignature("fun <A, B : Runnable> foo(a : A, b : List<B>, c: MutableList<in String?>) where B : List<Cloneable>")
|
||||
public <A, B extends Runnable & List<Cloneable>> void foo(A a, List<? extends B> b, List<? super String> list) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@ package test
|
||||
import java.util.*
|
||||
|
||||
public open class MethodWithTypeParameters : Object() {
|
||||
public open fun <erased A, erased B : Runnable> foo(p0 : A, p1 : List<out B>, p2: MutableList<in String?>) where B : List<Cloneable> {
|
||||
public open fun <erased A, erased B : Runnable> foo(p0 : A, p1 : List<B>, p2: MutableList<in String?>) where B : List<Cloneable> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ package test
|
||||
|
||||
public open class MethodWithTypeParameters : java.lang.Object {
|
||||
public constructor MethodWithTypeParameters()
|
||||
public open fun </*0*/ A, /*1*/ B> foo(/*0*/ p0 : A, /*1*/ p1 : jet.List<out B>, /*2*/ p2 : jet.MutableList<in jet.String?>) : Unit where B : java.lang.Runnable, B : jet.List<java.lang.Cloneable>
|
||||
public open fun </*0*/ A, /*1*/ B> foo(/*0*/ p0 : A, /*1*/ p1 : jet.List<B>, /*2*/ p2 : jet.MutableList<in jet.String?>) : Unit where B : java.lang.Runnable, B : jet.List<java.lang.Cloneable>
|
||||
}
|
||||
|
||||
@@ -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<in Number>)")
|
||||
public void foo(List<Number> list) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
public open class ConflictingProjectionKind : Object() {
|
||||
public open fun foo(p0: List<Number>?) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
public open class ConflictingProjectionKind : java.lang.Object {
|
||||
public constructor ConflictingProjectionKind()
|
||||
public open fun foo(/*0*/ p0 : jet.List<jet.Number>?) : Unit
|
||||
}
|
||||
@@ -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<out Number>)")
|
||||
public void foo(List<Number> list) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
public open class RedundantProjectionKind : Object() {
|
||||
public open fun foo(p0: List<Number>) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
public open class RedundantProjectionKind : java.lang.Object {
|
||||
public constructor RedundantProjectionKind()
|
||||
public open fun foo(/*0*/ p0 : jet.List<jet.Number>) : Unit
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
+10
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user