Rendering platform type for java.util.Map.Entry as kotlin.(Mutable)Map.(Mutable)Entry

This commit is contained in:
Andrey Breslav
2014-08-19 16:39:24 +04:00
parent dd2e95b3bc
commit fefadaa171
4 changed files with 39 additions and 21 deletions
@@ -2,5 +2,5 @@ package test
public open class WrongReturnTypeStructure { public open class WrongReturnTypeStructure {
public constructor WrongReturnTypeStructure() public constructor WrongReturnTypeStructure()
public open fun foo(/*0*/ p0: kotlin.String?, /*1*/ p1: kotlin.List<kotlin.Map.Entry<kotlin.String, kotlin.String>>?): kotlin.String? public open fun foo(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.(Mutable)List<kotlin.(Mutable)Map.(Mutable)Entry<kotlin.String!, kotlin.String!>!>!): kotlin.String!
} }
@@ -2,5 +2,5 @@ package test
public open class WrongValueParameterStructure1 { public open class WrongValueParameterStructure1 {
public constructor WrongValueParameterStructure1() public constructor WrongValueParameterStructure1()
public open fun foo(/*0*/ p0: kotlin.String?, /*1*/ p1: kotlin.List<kotlin.Map.Entry<kotlin.String, kotlin.String>>?): kotlin.String? public open fun foo(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.(Mutable)List<kotlin.(Mutable)Map.(Mutable)Entry<kotlin.String!, kotlin.String!>!>!): kotlin.String!
} }
@@ -2,5 +2,5 @@ package test
public open class WrongValueParameterStructure2 { public open class WrongValueParameterStructure2 {
public constructor WrongValueParameterStructure2() public constructor WrongValueParameterStructure2()
public open fun foo(/*0*/ p0: kotlin.String?, /*1*/ p1: kotlin.List<kotlin.Map.Entry<kotlin.String, kotlin.String>>?): kotlin.String? public open fun foo(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.(Mutable)List<kotlin.(Mutable)Map.(Mutable)Entry<kotlin.String!, kotlin.String!>!>!): kotlin.String!
} }
@@ -19,6 +19,7 @@ package org.jetbrains.jet.renderer;
import kotlin.Function1; import kotlin.Function1;
import kotlin.KotlinPackage; import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
@@ -346,27 +347,44 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
String kotlinPrefix = "kotlin."; String kotlinPrefix = "kotlin.";
String mutablePrefix = "Mutable"; String mutablePrefix = "Mutable";
// e.g. lower = kotlin.MutableList<Foo>, upper = kotlin.List<Foo?>? // java.util.List<Foo> -> (Mutable)List<Foo!>!
if (lowerRendered.startsWith(kotlinPrefix + mutablePrefix)) { String simpleCollection = replacePrefixes(
// List<Foo> lowerRendered, kotlinPrefix + mutablePrefix, upperRendered, kotlinPrefix, kotlinPrefix + "(" + mutablePrefix + ")"
String lowerWithoutPrefix = lowerRendered.substring(mutablePrefix.length() + kotlinPrefix.length()); );
if (differsOnlyInNullability(lowerWithoutPrefix, upperRendered.substring(kotlinPrefix.length()))) { if (simpleCollection != null) return simpleCollection;
return kotlinPrefix + "(" + mutablePrefix + ")" + lowerWithoutPrefix + "!"; // java.util.Map.Entry<Foo, Bar> -> (Mutable)Map.(Mutable)Entry<Foo!, Bar!>!
} String mutableEntry = replacePrefixes(
} lowerRendered, kotlinPrefix + "MutableMap.MutableEntry", upperRendered, kotlinPrefix + "Map.Entry",
else { kotlinPrefix + "(Mutable)Map.(Mutable)Entry"
String arrayPrefix = "kotlin.Array<"; );
String covariantArrayPrefix = "kotlin.Array<out "; if (mutableEntry != null) return mutableEntry;
if (lowerRendered.startsWith(arrayPrefix) && upperRendered.startsWith(covariantArrayPrefix)) {
String lowerWithoutPrefix = lowerRendered.substring(arrayPrefix.length()); // Foo[] -> Array<(out) Foo!>!
if (differsOnlyInNullability(lowerWithoutPrefix, upperRendered.substring(covariantArrayPrefix.length()))) { String array = replacePrefixes(
return arrayPrefix + "(out) " + lowerWithoutPrefix + "!"; lowerRendered, kotlinPrefix + "Array<", upperRendered, kotlinPrefix + "Array<out ",
} kotlinPrefix + "Array<(out) "
} );
} if (array != null) return array;
return "(" + renderType(lower) + ".." + renderType(upper) + ")"; return "(" + renderType(lower) + ".." + renderType(upper) + ")";
} }
@Nullable
private static String replacePrefixes(
@NotNull String lowerRendered,
@NotNull String lowerPrefix,
@NotNull String upperRendered,
@NotNull String upperPrefix,
@NotNull String foldedPrefix
) {
if (lowerRendered.startsWith(lowerPrefix) && upperRendered.startsWith(upperPrefix)) {
String lowerWithoutPrefix = lowerRendered.substring(lowerPrefix.length());
if (differsOnlyInNullability(lowerWithoutPrefix, upperRendered.substring(upperPrefix.length()))) {
return foldedPrefix + lowerWithoutPrefix + "!";
}
}
return null;
}
private static boolean differsOnlyInNullability(String lower, String upper) { private static boolean differsOnlyInNullability(String lower, String upper) {
return lower.equals(upper.replace("?", "")) return lower.equals(upper.replace("?", ""))
|| upper.endsWith("?") && ((lower + "?").equals(upper)) || (("(" + lower + ")?").equals(upper)); || upper.endsWith("?") && ((lower + "?").equals(upper)) || (("(" + lower + ")?").equals(upper));