Find Nothing only in own arguments of generic type to make type raw and generate ''?" for contravariant position instead of use raw type

This commit is contained in:
Zalim Bashorov
2015-12-07 16:20:06 +03:00
parent fa77808319
commit 1e0b133e19
3 changed files with 47 additions and 23 deletions
@@ -20,7 +20,6 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import kotlin.CollectionsKt;
import kotlin.Pair;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment;
@@ -581,7 +580,14 @@ public class JetTypeMapper {
@NotNull TypeMappingMode mode
) {
if (signatureVisitor != null) {
if (hasNothingInArguments(type) || type.getArguments().isEmpty()) {
// Nothing mapping rules:
// Map<Nothing, Foo> -> Map
// Map<Foo, List<Nothing>> -> Map<Foo, List>
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
// In<Nothing, Nothing> -> In
// Inv<in Nothing, Foo> -> Inv
if (hasNothingInNonContravariantPosition(type) || type.getArguments().isEmpty()) {
signatureVisitor.writeAsmType(asmType);
return;
}
@@ -638,7 +644,11 @@ public class JetTypeMapper {
TypeParameterDescriptor parameter = item.getFirst();
TypeProjection argument = item.getSecond();
if (argument.isStarProjection()) {
if (
argument.isStarProjection() ||
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
KotlinBuiltIns.isNothing(argument.getType()) && parameter.getVariance() == Variance.IN_VARIANCE
) {
signatureVisitor.writeUnboundedWildcard();
}
else {
@@ -656,22 +666,22 @@ public class JetTypeMapper {
}
}
private static boolean hasNothingInArguments(KotlinType jetType) {
boolean hasNothingInArguments = CollectionsKt.any(jetType.getArguments(), new Function1<TypeProjection, Boolean>() {
@Override
public Boolean invoke(TypeProjection projection) {
return KotlinBuiltIns.isNothingOrNullableNothing(projection.getType());
}
});
private static boolean hasNothingInNonContravariantPosition(KotlinType kotlinType) {
List<TypeParameterDescriptor> parameters = kotlinType.getConstructor().getParameters();
List<TypeProjection> arguments = kotlinType.getArguments();
if (hasNothingInArguments) return true;
for (int i = 0; i < arguments.size(); i++) {
TypeProjection projection = arguments.get(i);
return CollectionsKt.any(jetType.getArguments(), new Function1<TypeProjection, Boolean>() {
@Override
public Boolean invoke(TypeProjection projection) {
return !projection.isStarProjection() && hasNothingInArguments(projection.getType());
}
});
if (projection.isStarProjection()) continue;
KotlinType type = projection.getType();
if (KotlinBuiltIns.isNullableNothing(type) ||
KotlinBuiltIns.isNothing(type) && parameters.get(i).getVariance() != Variance.IN_VARIANCE) return true;
}
return false;
}
@NotNull
+10 -3
View File
@@ -1,6 +1,13 @@
class C<T>
fun f(p: Nothing, p1: C<Nothing>, p2: C<C<Nothing>>, p3: C<C<Nothing>>?): Nothing = throw Exception()
class I<in A, B>
class Z<A, B>
fun f(
p: Nothing, p1: C<Nothing>, p2: C<C<Nothing>>, p3: C<C<Nothing>>?,
p4: I<Nothing, Int>, p5: C<I<Nothing, String>>, p6: C<in Nothing>,
p7: Z<Nothing, String>, p8: Z<String, in Nothing>, p9: I<Nothing, Nothing>
): Nothing = throw Exception()
// method: NothingKt::f
// jvm signature: (Ljava/lang/Void;LC;LC;LC;)Ljava/lang/Void;
// generic signature: null
// jvm signature: (Ljava/lang/Void;LC;LC;LC;LI;LC;LC;LZ;LZ;LI;)Ljava/lang/Void;
// generic signature: (Ljava/lang/Void;LC;LC<LC;>;LC<LC;>;LI<*Ljava/lang/Integer;>;LC<LI<*Ljava/lang/String;>;>;LC;LZ;LZ;LI;)Ljava/lang/Void;
+10 -3
View File
@@ -1,6 +1,13 @@
class C<T>
fun f(p: Nothing?, p1: C<Nothing?>, p2: C<C<Nothing?>>, p3: C<C<Nothing?>>?): Nothing? = throw Exception()
class I<in A, B>
class Z<A, B>
fun f(
p: Nothing?, p1: C<Nothing?>, p2: C<C<Nothing?>>, p3: C<C<Nothing?>>?,
p4: I<Nothing?, Int>, p5: C<I<Nothing?, String>>, p6: C<in Nothing?>,
p7: Z<Nothing?, String>, p8: Z<String, in Nothing?>, p9: I<Nothing?, Nothing>
): Nothing? = throw Exception()
// method: NullableNothingKt::f
// jvm signature: (Ljava/lang/Void;LC;LC;LC;)Ljava/lang/Void;
// generic signature: null
// jvm signature: (Ljava/lang/Void;LC;LC;LC;LI;LC;LC;LZ;LZ;LI;)Ljava/lang/Void;
// generic signature: (Ljava/lang/Void;LC;LC<LC;>;LC<LC;>;LI;LC<LI;>;LC;LZ;LZ;LI;)Ljava/lang/Void;