diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/CollectionClassMapping.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/CollectionClassMapping.java deleted file mode 100644 index 19d9f3e3b5c..00000000000 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/CollectionClassMapping.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.resolve.jvm.kotlinSignature; - -import com.google.common.collect.ImmutableBiMap; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.descriptors.ClassDescriptor; -import org.jetbrains.kotlin.name.ClassId; -import org.jetbrains.kotlin.platform.JavaToKotlinClassMapBuilder; - -public class CollectionClassMapping extends JavaToKotlinClassMapBuilder { - private static CollectionClassMapping instance = null; - - @NotNull - public static CollectionClassMapping getInstance() { - if (instance == null) { - instance = new CollectionClassMapping(); - } - return instance; - } - - private ImmutableBiMap.Builder mapBuilder = ImmutableBiMap.builder(); - private final ImmutableBiMap mutableToReadOnlyMap; - - private CollectionClassMapping() { - init(); - mutableToReadOnlyMap = mapBuilder.build(); - mapBuilder = null; - } - - @Override - protected void register(@NotNull ClassId javaClassId, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) { - // do nothing - } - - @Override - protected void register( - @NotNull ClassId javaClassId, - @NotNull ClassDescriptor kotlinDescriptor, - @NotNull ClassDescriptor kotlinMutableDescriptor - ) { - 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 readOnly = mutableToReadOnlyMap.get(mutable); - if (readOnly == null) { - throw new IllegalArgumentException("Given class " + mutable + " is not a mutable collection"); - } - 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; - } -} diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java index 7e02bee4f33..e9768306be6 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor; import org.jetbrains.kotlin.load.java.structure.JavaMethod; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.platform.JavaToKotlinClassMap; import org.jetbrains.kotlin.renderer.DescriptorRenderer; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.jvm.JavaResolverUtils; @@ -619,8 +620,6 @@ public class SignaturesPropagationData { } ClassDescriptor klass = (ClassDescriptor) classifier; - CollectionClassMapping collectionMapping = CollectionClassMapping.getInstance(); - boolean someSupersMutable = false; boolean someSupersCovariantReadOnly = false; boolean someSupersNotCovariantReadOnly = false; @@ -629,10 +628,10 @@ public class SignaturesPropagationData { if (classifierFromSuper instanceof ClassDescriptor) { ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper; - if (collectionMapping.isMutableCollection(classFromSuper)) { + if (JavaToKotlinClassMap.INSTANCE.isMutableCollection(classFromSuper)) { someSupersMutable = true; } - else if (collectionMapping.isReadOnlyCollection(classFromSuper)) { + else if (JavaToKotlinClassMap.INSTANCE.isReadOnlyCollection(classFromSuper)) { if (typeFromSuper.varianceOfPosition == Variance.OUT_VARIANCE) { someSupersCovariantReadOnly = true; } @@ -648,13 +647,13 @@ public class SignaturesPropagationData { return classifier; } else if (someSupersMutable) { - if (collectionMapping.isReadOnlyCollection(klass)) { - return collectionMapping.convertReadOnlyToMutable(klass); + if (JavaToKotlinClassMap.INSTANCE.isReadOnlyCollection(klass)) { + return JavaToKotlinClassMap.INSTANCE.convertReadOnlyToMutable(klass); } } else if (someSupersNotCovariantReadOnly || someSupersCovariantReadOnly) { - if (collectionMapping.isMutableCollection(klass)) { - return collectionMapping.convertMutableToReadOnly(klass); + if (JavaToKotlinClassMap.INSTANCE.isMutableCollection(klass)) { + return JavaToKotlinClassMap.INSTANCE.convertMutableToReadOnly(klass); } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java index cd05a462b8c..0ac0252d1a1 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/platform/JavaToKotlinClassMap.java @@ -35,6 +35,9 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements private final Map javaToKotlinCovariant = new HashMap(); private final Map kotlinToJava = new HashMap(); + private final Map mutableToReadOnly = new HashMap(); + private final Map readOnlyToMutable = new HashMap(); + private JavaToKotlinClassMap() { init(); } @@ -95,6 +98,9 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements addJavaToKotlinCovariant(javaClassId, kotlinMutableDescriptor); addKotlinToJava(javaClassId, kotlinDescriptor); addKotlinToJava(javaClassId, kotlinMutableDescriptor); + + mutableToReadOnly.put(kotlinMutableDescriptor, kotlinDescriptor); + readOnlyToMutable.put(kotlinDescriptor, kotlinMutableDescriptor); } private void addJavaToKotlin(@NotNull ClassId javaClassId, @NotNull ClassDescriptor kotlinDescriptor) { @@ -133,6 +139,32 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements return mapPlatformClass(className.toSafe()); } + public boolean isMutableCollection(@NotNull ClassDescriptor mutable) { + return mutableToReadOnly.containsKey(mutable); + } + + public boolean isReadOnlyCollection(@NotNull ClassDescriptor readOnly) { + return readOnlyToMutable.containsKey(readOnly); + } + + @NotNull + public ClassDescriptor convertMutableToReadOnly(@NotNull ClassDescriptor mutable) { + ClassDescriptor readOnly = mutableToReadOnly.get(mutable); + if (readOnly == null) { + throw new IllegalArgumentException("Given class " + mutable + " is not a mutable collection"); + } + return readOnly; + } + + @NotNull + public ClassDescriptor convertReadOnlyToMutable(@NotNull ClassDescriptor readOnly) { + ClassDescriptor mutable = readOnlyToMutable.get(readOnly); + if (mutable == null) { + throw new IllegalArgumentException("Given class " + readOnly + " is not a read-only collection"); + } + return mutable; + } + // TODO: get rid of this method, it's unclear what it does @NotNull public List allKotlinClasses() { diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt index 2293c1fd352..31652de14e3 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt @@ -16,16 +16,16 @@ package org.jetbrains.kotlin.idea.util -import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.resolve.jvm.kotlinSignature.CollectionClassMapping import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.resolve.scopes.JetScope -import java.util.LinkedHashSet +import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.substitute +import java.util.LinkedHashSet fun JetType.makeNullable() = TypeUtils.makeNullable(this) fun JetType.makeNotNullable() = TypeUtils.makeNotNullable(this) @@ -41,7 +41,7 @@ public fun approximateFlexibleTypes(jetType: JetType, outermost: Boolean = true) if (jetType.isFlexible()) { val flexible = jetType.flexibility() val lowerClass = flexible.lowerBound.getConstructor().getDeclarationDescriptor() as? ClassDescriptor? - val isCollection = lowerClass != null && CollectionClassMapping.getInstance().isMutableCollection(lowerClass) + val isCollection = lowerClass != null && JavaToKotlinClassMap.INSTANCE.isMutableCollection(lowerClass) // (Mutable)Collection! -> MutableCollection? // Foo<(Mutable)Collection!>! -> Foo>? // Foo! -> Foo?