diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AlternativeSignatureParsing.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AlternativeSignatureParsing.java index afb80800966..bbcee33fe6e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AlternativeSignatureParsing.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/AlternativeSignatureParsing.java @@ -29,10 +29,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.JetTypeImpl; -import org.jetbrains.jet.lang.types.TypeProjection; -import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.resolve.DescriptorRenderer; @@ -110,7 +107,28 @@ class AlternativeSignatureParsing { TypeProjection argument = arguments.get(i); JetType alternativeType = computeAlternativeTypeFromAnnotation(argumentAlternativeTypeElement, argument.getType()); - altArguments.add(new TypeProjection(argument.getProjectionKind(), alternativeType)); + Variance variance = argument.getProjectionKind(); + if (type instanceof JetUserType) { + JetTypeProjection typeProjection = ((JetUserType) type).getTypeArguments().get(i); + Variance altVariance = Variance.INVARIANT; + switch (typeProjection.getProjectionKind()) { + case IN: + altVariance = Variance.IN_VARIANCE; + break; + case OUT: + altVariance = Variance.OUT_VARIANCE; + break; + case STAR: + throw new AlternativeSignatureMismatchException( + "Star projection is not available in alternative signatures"); + default: + } + if (altVariance != variance) { + throw new AlternativeSignatureMismatchException(String.format( + "Variance mismatch, actual: %s, in alternative signature: %s", variance, altVariance)); + } + } + altArguments.add(new TypeProjection(variance, alternativeType)); } return new JetTypeImpl(autoType.getAnnotations(), autoType.getConstructor(), false, altArguments, autoType.getMemberScope()); diff --git a/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.java b/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.java new file mode 100644 index 00000000000..c8269205606 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.java @@ -0,0 +1,15 @@ +package test; + +import java.lang.Number; +import java.lang.UnsupportedOperationException; +import java.util.*; +import java.util.List; + +import jet.runtime.typeinfo.KotlinSignature; + +public class WrongTypeVariance { + @KotlinSignature("fun copy(a : List, b : List) : List") + public List copy(List from, List to) { + throw new UnsupportedOperationException(); + } +} diff --git a/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.kt b/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.kt new file mode 100644 index 00000000000..c66c998e196 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.kt @@ -0,0 +1,9 @@ +package test + +import java.util.* + +public open class WrongTypeVariance : Object() { + public open fun copy(p0 : List?, p1 : List?) : List? { + throw UnsupportedOperationException() + } +} diff --git a/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.txt b/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.txt new file mode 100644 index 00000000000..ddca82de9ef --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/kotlinSignature/error/WrongTypeVariance.txt @@ -0,0 +1,6 @@ +namespace test + +public open class test.WrongTypeVariance : java.lang.Object { + public final /*constructor*/ fun (): test.WrongTypeVariance + public open fun copy(/*0*/ p0: java.util.List?, /*1*/ p1: java.util.List?): java.util.List? +}