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);
}
}