Rendering flexible types with "!" and optional parts
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package test;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.lang.String;
|
||||
import java.util.*;
|
||||
|
||||
public class Rendering {
|
||||
|
||||
class A_Plain {}
|
||||
|
||||
class B_Super {}
|
||||
|
||||
class C_Sub extends B_Super {}
|
||||
|
||||
class D_SuperG<T> {}
|
||||
|
||||
class E_SubG extends D_SuperG<String> {}
|
||||
|
||||
interface F_Array {
|
||||
void foo1(String[] strings);
|
||||
void foo2(List<String>[] strings);
|
||||
void foo3(Integer... args);
|
||||
void foo4(String... args);
|
||||
void foo5(List<String>... args);
|
||||
}
|
||||
|
||||
interface G_Collections {
|
||||
void foo1(Iterator<String> x);
|
||||
void foo2(Iterable<String> x);
|
||||
void foo3(Collection<String> x);
|
||||
void foo4(List<String> x);
|
||||
void foo5(Set<String> x);
|
||||
void foo6(Map<String, String> x);
|
||||
void foo7(Map.Entry<String, String> x);
|
||||
}
|
||||
|
||||
interface H_Raw {
|
||||
void foo1(List x);
|
||||
void foo2(D_SuperG x);
|
||||
}
|
||||
|
||||
interface I_Wildcard {
|
||||
void foo1(List<? extends String> x);
|
||||
void foo2(List<? super String> x);
|
||||
void foo3(List<?> x);
|
||||
void foo4(D_SuperG<? extends String> x);
|
||||
void foo5(D_SuperG<? super String> x);
|
||||
void foo6(D_SuperG<?> x);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package test
|
||||
|
||||
public open class Rendering {
|
||||
public constructor Rendering()
|
||||
|
||||
public/*package*/ open inner class A_Plain {
|
||||
public/*package*/ constructor A_Plain()
|
||||
}
|
||||
|
||||
public/*package*/ open inner class B_Super {
|
||||
public/*package*/ constructor B_Super()
|
||||
}
|
||||
|
||||
public/*package*/ open inner class C_Sub : test.Rendering.B_Super {
|
||||
public/*package*/ constructor C_Sub()
|
||||
}
|
||||
|
||||
public/*package*/ open inner class D_SuperG</*0*/ T> {
|
||||
public/*package*/ constructor D_SuperG</*0*/ T>()
|
||||
}
|
||||
|
||||
public/*package*/ open inner class E_SubG : test.Rendering.D_SuperG<kotlin.String!> {
|
||||
public/*package*/ constructor E_SubG()
|
||||
}
|
||||
|
||||
public/*package*/ trait F_Array {
|
||||
public abstract fun foo1(/*0*/ p0: kotlin.Array<(out) kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo2(/*0*/ p0: kotlin.Array<(out) kotlin.(Mutable)List<kotlin.String!>!>!): kotlin.Unit
|
||||
public abstract fun foo3(/*0*/ vararg p0: kotlin.Int! /*kotlin.Array<(out) kotlin.Int!>!*/): kotlin.Unit
|
||||
public abstract fun foo4(/*0*/ vararg p0: kotlin.String! /*kotlin.Array<(out) kotlin.String!>!*/): kotlin.Unit
|
||||
public abstract fun foo5(/*0*/ vararg p0: kotlin.(Mutable)List<kotlin.String!>! /*kotlin.Array<(out) kotlin.(Mutable)List<kotlin.String!>!>!*/): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ trait G_Collections {
|
||||
public abstract fun foo1(/*0*/ p0: kotlin.(Mutable)Iterator<kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo2(/*0*/ p0: kotlin.(Mutable)Iterable<kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo3(/*0*/ p0: kotlin.(Mutable)Collection<kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo4(/*0*/ p0: kotlin.(Mutable)List<kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo5(/*0*/ p0: kotlin.(Mutable)Set<kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo6(/*0*/ p0: kotlin.(Mutable)Map<kotlin.String!, kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo7(/*0*/ p0: (kotlin.MutableMap.MutableEntry<kotlin.String!, kotlin.String!>..kotlin.Map.Entry<kotlin.String!, kotlin.String!>?)): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ trait H_Raw {
|
||||
public abstract fun foo1(/*0*/ p0: (kotlin.MutableList<out kotlin.Any?>..kotlin.List<kotlin.Any?>?)): kotlin.Unit
|
||||
public abstract fun foo2(/*0*/ p0: test.Rendering.D_SuperG<out kotlin.Any?>!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ trait I_Wildcard {
|
||||
public abstract fun foo1(/*0*/ p0: (kotlin.MutableList<out kotlin.String!>..kotlin.List<kotlin.String!>?)): kotlin.Unit
|
||||
public abstract fun foo2(/*0*/ p0: kotlin.(Mutable)List<in kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo3(/*0*/ p0: (kotlin.MutableList<out kotlin.Any?>..kotlin.List<kotlin.Any?>?)): kotlin.Unit
|
||||
public abstract fun foo4(/*0*/ p0: test.Rendering.D_SuperG<out kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo5(/*0*/ p0: test.Rendering.D_SuperG<in kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun foo6(/*0*/ p0: test.Rendering.D_SuperG<out kotlin.Any?>!): kotlin.Unit
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ import java.util.regex.Pattern;
|
||||
public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
@TestMetadata("compiler/testData/loadJava/compiledJava")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({CompiledJava.Annotations.class, CompiledJava.Constructor.class, CompiledJava.JavaBean.class, CompiledJava.KotlinSignature.class, CompiledJava.Library.class, CompiledJava.Modality.class, CompiledJava.Mutability.class, CompiledJava.NotNull.class, CompiledJava.ProtectedPackage.class, CompiledJava.ProtectedStatic.class, CompiledJava.Sam.class, CompiledJava.SignaturePropagation.class, CompiledJava.Static.class, CompiledJava.Vararg.class})
|
||||
@InnerTestClasses({CompiledJava.Annotations.class, CompiledJava.Constructor.class, CompiledJava.JavaBean.class, CompiledJava.KotlinSignature.class, CompiledJava.Library.class, CompiledJava.Modality.class, CompiledJava.Mutability.class, CompiledJava.NotNull.class, CompiledJava.ProtectedPackage.class, CompiledJava.ProtectedStatic.class, CompiledJava.Rendering.class, CompiledJava.Sam.class, CompiledJava.SignaturePropagation.class, CompiledJava.Static.class, CompiledJava.Vararg.class})
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
public static class CompiledJava extends AbstractLoadJavaTest {
|
||||
public void testAllFilesPresentInCompiledJava() throws Exception {
|
||||
@@ -1400,6 +1400,22 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadJava/compiledJava/rendering")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
public static class Rendering extends AbstractLoadJavaTest {
|
||||
public void testAllFilesPresentInRendering() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledJava/rendering"), Pattern.compile("^(.+)\\.java$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("Rendering.java")
|
||||
public void testRendering() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/rendering/Rendering.java");
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/loadJava/compiledJava/sam")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({Sam.Adapters.class})
|
||||
|
||||
@@ -301,9 +301,14 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
if (type instanceof FlexibleType && debugMode) {
|
||||
if (type instanceof FlexibleType) {
|
||||
FlexibleType flexibleType = (FlexibleType) type;
|
||||
return "(" + renderType(flexibleType.getLowerBound()) + ".." + renderType(flexibleType.getUpperBound()) + ")";
|
||||
if (!debugMode) {
|
||||
return renderFlexibleType(flexibleType);
|
||||
}
|
||||
else {
|
||||
return "(" + renderType(flexibleType.getLowerBound()) + ".." + renderType(flexibleType.getUpperBound()) + ")";
|
||||
}
|
||||
}
|
||||
if (type instanceof LazyType && debugMode) {
|
||||
return type.toString();
|
||||
@@ -317,6 +322,45 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
||||
return renderDefaultType(type);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String renderFlexibleType(@NotNull FlexibleType type) {
|
||||
JetType lower = type.getLowerBound();
|
||||
JetType upper = type.getUpperBound();
|
||||
|
||||
String lowerRendered = renderDefaultType(lower);
|
||||
String upperRendered = renderDefaultType(upper);
|
||||
|
||||
if (differsOnlyInNullability(lowerRendered, upperRendered)) {
|
||||
return lowerRendered + "!";
|
||||
}
|
||||
|
||||
String kotlinPrefix = "kotlin.";
|
||||
String mutablePrefix = "Mutable";
|
||||
// e.g. lower = kotlin.MutableList<Foo>, upper = kotlin.List<Foo?>?
|
||||
if (lowerRendered.startsWith(kotlinPrefix + mutablePrefix)) {
|
||||
// List<Foo>
|
||||
String lowerWithoutPrefix = lowerRendered.substring(mutablePrefix.length() + kotlinPrefix.length());
|
||||
if (differsOnlyInNullability(lowerWithoutPrefix, upperRendered.substring(kotlinPrefix.length()))) {
|
||||
return kotlinPrefix + "(" + mutablePrefix + ")" + lowerWithoutPrefix + "!";
|
||||
}
|
||||
}
|
||||
else {
|
||||
String arrayPrefix = "kotlin.Array<";
|
||||
String covariantArrayPrefix = "kotlin.Array<out ";
|
||||
if (lowerRendered.startsWith(arrayPrefix) && upperRendered.startsWith(covariantArrayPrefix)) {
|
||||
String lowerWithoutPrefix = lowerRendered.substring(arrayPrefix.length());
|
||||
if (differsOnlyInNullability(lowerWithoutPrefix, upperRendered.substring(covariantArrayPrefix.length()))) {
|
||||
return arrayPrefix + "(out) " + lowerWithoutPrefix + "!";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "(" + renderType(lower) + ".." + renderType(upper) + ")";
|
||||
}
|
||||
|
||||
private static boolean differsOnlyInNullability(String lower, String upper) {
|
||||
return lower.equals(upper.replace("?", "")) || upper.endsWith("?") && (lower + "?").equals(upper);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String renderTypeArguments(@NotNull List<TypeProjection> typeArguments) {
|
||||
|
||||
Reference in New Issue
Block a user