Supported propagating read-onliness.

#KT-2776 in progress
This commit is contained in:
Evgeny Gerashchenko
2012-11-12 15:37:57 +04:00
parent 89b413b7ad
commit 044487cf37
13 changed files with 264 additions and 2 deletions
@@ -0,0 +1,74 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.ImmutableBiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
public class MutableReadOnlyCollectionsMap extends JavaToKotlinClassMapBuilder {
private static MutableReadOnlyCollectionsMap instance = null;
@NotNull
public static MutableReadOnlyCollectionsMap getInstance() {
if (instance == null) {
instance = new MutableReadOnlyCollectionsMap();
}
return instance;
}
private ImmutableBiMap.Builder<ClassDescriptor, ClassDescriptor> mapBuilder = ImmutableBiMap.builder();
private final ImmutableBiMap<ClassDescriptor, ClassDescriptor> mutableToReadOnlyMap;
private MutableReadOnlyCollectionsMap() {
init();
mutableToReadOnlyMap = mapBuilder.build();
mapBuilder = null;
}
@Override
void register(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) {
// do nothing
}
@Override
void register(
@NotNull Class<?> javaClass,
@NotNull ClassDescriptor kotlinDescriptor,
@NotNull ClassDescriptor kotlinMutableDescriptor,
@NotNull Direction direction
) {
mapBuilder.put(kotlinMutableDescriptor, kotlinDescriptor);
}
public boolean isMutableCollection(@NotNull ClassDescriptor mutable) {
return mutableToReadOnlyMap.containsKey(mutable);
}
public boolean isReadOnlyCollection(@NotNull ClassDescriptor immutable) {
return mutableToReadOnlyMap.containsValue(immutable);
}
@NotNull
public ClassDescriptor convertMutableToReadOnly(@NotNull ClassDescriptor mutable) {
ClassDescriptor immutable = mutableToReadOnlyMap.get(mutable);
if (immutable == null) {
throw new IllegalArgumentException("Given class " + mutable + " is not a mutable collection");
}
return immutable;
}
}
@@ -304,7 +304,7 @@ public final class JavaFunctionResolver {
boolean resultNullable = returnTypeMustBeNullable(autoType, typesFromSuper, covariantPosition);
List<TypeProjection> resultArguments = getTypeArgsOfReturnType(autoType, typesFromSuper);
JetScope resultScope;
ClassifierDescriptor classifierDescriptor = autoType.getConstructor().getDeclarationDescriptor();
ClassifierDescriptor classifierDescriptor = getReturnTypeClassifier(autoType, typesFromSuper);
if (classifierDescriptor instanceof ClassDescriptor) {
resultScope = ((ClassDescriptor) classifierDescriptor).getMemberScope(resultArguments);
}
@@ -313,7 +313,7 @@ public final class JavaFunctionResolver {
}
return new JetTypeImpl(autoType.getAnnotations(),
autoType.getConstructor(),
classifierDescriptor.getTypeConstructor(),
resultNullable,
resultArguments,
resultScope);
@@ -414,6 +414,41 @@ public final class JavaFunctionResolver {
return someSupersNullable && autoType.isNullable();
}
@NotNull
private static ClassifierDescriptor getReturnTypeClassifier(@NotNull JetType autoType, @NotNull Collection<JetType> typesFromSuper) {
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
if (!(classifier instanceof ClassDescriptor)) {
return classifier;
}
ClassDescriptor clazz = (ClassDescriptor) classifier;
MutableReadOnlyCollectionsMap collectionsMap = MutableReadOnlyCollectionsMap.getInstance();
if (collectionsMap.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;
if (collectionsMap.isMutableCollection(classFromSuper)) {
someSupersMutable = true;
}
else if (collectionsMap.isReadOnlyCollection(classFromSuper)) {
someSupersReadOnly = true;
}
}
}
if (someSupersReadOnly && !someSupersMutable) {
return collectionsMap.convertMutableToReadOnly(clazz);
}
}
return classifier;
}
private static boolean isEnumSpecialMethod(@NotNull FunctionDescriptor functionDescriptor) {
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
String methodName = functionDescriptor.getName().getName();