From 1e0b133e191c8072173db7911e084eb0139c5638 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Mon, 7 Dec 2015 16:20:06 +0300 Subject: [PATCH] Find Nothing only in own arguments of generic type to make type raw and generate ''?" for contravariant position instead of use raw type --- .../kotlin/codegen/state/JetTypeMapper.java | 44 ++++++++++++------- .../writeSignature/nothing/nothing.kt | 13 ++++-- .../writeSignature/nothing/nullableNothing.kt | 13 ++++-- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 23aa4dbacd4..5ae570ccc4e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -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 -> Map + // Map> -> Map + // In == In<*, Foo> -> In + // In -> In + // Inv -> 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 == In<*, Foo> -> In + 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() { - @Override - public Boolean invoke(TypeProjection projection) { - return KotlinBuiltIns.isNothingOrNullableNothing(projection.getType()); - } - }); + private static boolean hasNothingInNonContravariantPosition(KotlinType kotlinType) { + List parameters = kotlinType.getConstructor().getParameters(); + List 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() { - @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 diff --git a/compiler/testData/writeSignature/nothing/nothing.kt b/compiler/testData/writeSignature/nothing/nothing.kt index 60147cc1408..4c02c33785b 100644 --- a/compiler/testData/writeSignature/nothing/nothing.kt +++ b/compiler/testData/writeSignature/nothing/nothing.kt @@ -1,6 +1,13 @@ class C -fun f(p: Nothing, p1: C, p2: C>, p3: C>?): Nothing = throw Exception() +class I +class Z + +fun f( + p: Nothing, p1: C, p2: C>, p3: C>?, + p4: I, p5: C>, p6: C, + p7: Z, p8: Z, p9: I +): 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;LI<*Ljava/lang/Integer;>;LC;>;LC;LZ;LZ;LI;)Ljava/lang/Void; diff --git a/compiler/testData/writeSignature/nothing/nullableNothing.kt b/compiler/testData/writeSignature/nothing/nullableNothing.kt index 88e219f8360..4108b817493 100644 --- a/compiler/testData/writeSignature/nothing/nullableNothing.kt +++ b/compiler/testData/writeSignature/nothing/nullableNothing.kt @@ -1,6 +1,13 @@ class C -fun f(p: Nothing?, p1: C, p2: C>, p3: C>?): Nothing? = throw Exception() +class I +class Z + +fun f( + p: Nothing?, p1: C, p2: C>, p3: C>?, + p4: I, p5: C>, p6: C, + p7: Z, p8: Z, p9: I +): 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;LI;LC;LC;LZ;LZ;LI;)Ljava/lang/Void;