Supported propagation of mutability in parameter position.

#KT-2776 in progress
This commit is contained in:
Evgeny Gerashchenko
2012-11-22 15:02:57 +04:00
parent a937d6be91
commit 795b3bfbe0
10 changed files with 152 additions and 20 deletions
@@ -65,10 +65,19 @@ public class CollectionClassMapping extends JavaToKotlinClassMapBuilder {
@NotNull
public ClassDescriptor convertMutableToReadOnly(@NotNull ClassDescriptor mutable) {
ClassDescriptor immutable = mutableToReadOnlyMap.get(mutable);
if (immutable == null) {
ClassDescriptor readOnly = mutableToReadOnlyMap.get(mutable);
if (readOnly == null) {
throw new IllegalArgumentException("Given class " + mutable + " is not a mutable collection");
}
return immutable;
return readOnly;
}
@NotNull
public ClassDescriptor convertReadOnlyToMutable(@NotNull ClassDescriptor readOnly) {
ClassDescriptor mutable = mutableToReadOnlyMap.inverse().get(readOnly);
if (mutable == null) {
throw new IllegalArgumentException("Given class " + readOnly + " is not a read-only collection");
}
return mutable;
}
}
@@ -140,7 +140,7 @@ public class SignaturesPropagation {
}
boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, covariantPosition, reportError);
ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper);
ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper, covariantPosition, reportError);
List<TypeProjection> resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper, reportError);
JetScope resultScope;
if (resultClassifier instanceof ClassDescriptor) {
@@ -334,7 +334,12 @@ public class SignaturesPropagation {
}
@NotNull
private static ClassifierDescriptor modifyTypeClassifier(@NotNull JetType autoType, @NotNull List<JetType> typesFromSuper) {
private static ClassifierDescriptor modifyTypeClassifier(
@NotNull JetType autoType,
@NotNull List<JetType> typesFromSuper,
boolean covariantPosition,
@NotNull Function1<String, Void> reportError
) {
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
if (!(classifier instanceof ClassDescriptor)) {
assert classifier != null : "no declaration descriptor for type " + autoType;
@@ -344,25 +349,43 @@ public class SignaturesPropagation {
CollectionClassMapping collectionMapping = CollectionClassMapping.getInstance();
if (collectionMapping.isMutableCollection(clazz)) {
boolean someSupersMutable = false;
boolean someSupersReadOnly = false;
for (JetType typeFromSuper : typesFromSuper) {
ClassifierDescriptor classifierFromSuper = typeFromSuper.getConstructor().getDeclarationDescriptor();
if (classifierFromSuper instanceof ClassDescriptor) {
ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
boolean someSupersMutable = false;
boolean someSupersReadOnly = false;
for (JetType typeFromSuper : typesFromSuper) {
ClassifierDescriptor classifierFromSuper = typeFromSuper.getConstructor().getDeclarationDescriptor();
if (classifierFromSuper instanceof ClassDescriptor) {
ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
if (collectionMapping.isMutableCollection(classFromSuper)) {
someSupersMutable = true;
}
else if (collectionMapping.isReadOnlyCollection(classFromSuper)) {
someSupersReadOnly = true;
}
if (collectionMapping.isMutableCollection(classFromSuper)) {
someSupersMutable = true;
}
else if (collectionMapping.isReadOnlyCollection(classFromSuper)) {
someSupersReadOnly = true;
}
}
}
if (someSupersReadOnly && !someSupersMutable) {
if (covariantPosition) {
if (collectionMapping.isMutableCollection(clazz)) {
if (someSupersReadOnly && !someSupersMutable) {
return collectionMapping.convertMutableToReadOnly(clazz);
}
}
}
else {
if (someSupersMutable == someSupersReadOnly) {
//noinspection ConstantConditions
if (someSupersMutable && someSupersReadOnly) {
reportError.invoke("Incompatible types in superclasses: " + typesFromSuper);
}
return classifier;
}
if (someSupersMutable && collectionMapping.isReadOnlyCollection(clazz)) {
return collectionMapping.convertReadOnlyToMutable(clazz);
}
if (someSupersReadOnly && collectionMapping.isMutableCollection(clazz)) {
return collectionMapping.convertMutableToReadOnly(clazz);
}
}
@@ -0,0 +1,18 @@
package test;
import org.jetbrains.annotations.NotNull;
import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
import java.util.*;
public interface InheritMutability {
public interface Super {
@KotlinSignature("fun foo(p: MutableList<String>)")
void foo(List<String> p);
}
public interface Sub extends Super {
void foo(List<String> p);
}
}
@@ -0,0 +1,12 @@
package test
public trait InheritMutability: Object {
public trait Super: Object {
public fun foo(p0: MutableList<String>)
}
public trait Sub: Super {
override fun foo(p0: MutableList<String>)
}
}
@@ -0,0 +1,10 @@
namespace test
public abstract trait test.InheritMutability : java.lang.Object {
public abstract trait test.InheritMutability.Sub : test.InheritMutability.Super {
public abstract override /*1*/ fun foo(/*0*/ p0: jet.MutableList<jet.String>): jet.Tuple0
}
public abstract trait test.InheritMutability.Super : java.lang.Object {
public abstract fun foo(/*0*/ p0: jet.MutableList<jet.String>): jet.Tuple0
}
}
@@ -0,0 +1,18 @@
package test;
import org.jetbrains.annotations.NotNull;
import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.jet.jvm.compiler.annotation.ExpectLoadError;
import java.util.*;
public interface InheritReadOnliness {
public interface Super {
@KotlinSignature("fun foo(p: List<String>)")
void foo(List<String> p);
}
public interface Sub extends Super {
void foo(List<String> p);
}
}
@@ -0,0 +1,12 @@
package test
public trait InheritReadOnliness: Object {
public trait Super: Object {
public fun foo(p0: List<String>)
}
public trait Sub: Super {
override fun foo(p0: List<String>)
}
}
@@ -0,0 +1,10 @@
namespace test
public abstract trait test.InheritReadOnliness : java.lang.Object {
public abstract trait test.InheritReadOnliness.Sub : test.InheritReadOnliness.Super {
public abstract override /*1*/ fun foo(/*0*/ p0: jet.List<jet.String>): jet.Tuple0
}
public abstract trait test.InheritReadOnliness.Super : java.lang.Object {
public abstract fun foo(/*0*/ p0: jet.List<jet.String>): jet.Tuple0
}
}
@@ -451,11 +451,21 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/kotlinSignature/propagation/parameter"), "java", true);
}
@TestMetadata("InheritMutability.java")
public void testInheritMutability() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.java");
}
@TestMetadata("InheritNullability.java")
public void testInheritNullability() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNullability.java");
}
@TestMetadata("InheritReadOnliness.java")
public void testInheritReadOnliness() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritReadOnliness.java");
}
@TestMetadata("NotNullToNullable.java")
public void testNotNullToNullable() throws Exception {
doTest("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.java");
@@ -1341,11 +1341,21 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/kotlinSignature/propagation/parameter"), "kt", true);
}
@TestMetadata("InheritMutability.kt")
public void testInheritMutability() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritMutability.kt");
}
@TestMetadata("InheritNullability.kt")
public void testInheritNullability() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritNullability.kt");
}
@TestMetadata("InheritReadOnliness.kt")
public void testInheritReadOnliness() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/InheritReadOnliness.kt");
}
@TestMetadata("NotNullToNullable.kt")
public void testNotNullToNullable() throws Exception {
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/parameter/NotNullToNullable.kt");