From bab20717ee203f40ff1a46ea49dd2db8d208b08c Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 4 Sep 2012 16:50:08 +0400 Subject: [PATCH] KT-2688 Provide mutable/immutable interfaces for Java collections #KT-2688 fixed --- .../jet/codegen/KotlinToJavaTypesMap.java | 48 ++++-- .../resolve/java/JavaToKotlinTypesMap.java | 29 +++- compiler/frontend/src/jet/Collections.jet | 140 ++++++++++++++++++ compiler/frontend/src/jet/Iterators.jet | 21 +++ .../lang/types/lang/JetStandardLibrary.java | 68 ++++++++- 5 files changed, 286 insertions(+), 20 deletions(-) create mode 100644 compiler/frontend/src/jet/Collections.jet diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java index 75ed05d7a4f..163663ed3fb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/KotlinToJavaTypesMap.java @@ -33,10 +33,8 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.PrimitiveType; import org.jetbrains.jet.lang.types.ref.ClassName; -import java.util.Map; -import java.util.Set; - -import static org.jetbrains.jet.codegen.AsmTypeConstants.*; +import java.lang.annotation.Annotation; +import java.util.*; /** * @author svtk @@ -64,18 +62,36 @@ public class KotlinToJavaTypesMap { private void init() { JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance(); - register(JetStandardClasses.getAny(), OBJECT_TYPE); - register(standardLibrary.getNumber(), JAVA_NUMBER_TYPE); - register(standardLibrary.getString(), JAVA_STRING_TYPE); - register(standardLibrary.getThrowable(), JAVA_THROWABLE_TYPE); - register(standardLibrary.getCharSequence(), JAVA_CHAR_SEQUENCE_TYPE); - register(standardLibrary.getComparable(), JAVA_COMPARABLE_TYPE); - register(standardLibrary.getEnum(), JAVA_ENUM_TYPE); - register(standardLibrary.getAnnotation(), JAVA_ANNOTATION_TYPE); - register(standardLibrary.getIterable(), JAVA_ITERABLE_TYPE); - register(standardLibrary.getMutableIterable(), JAVA_ITERABLE_TYPE); - register(standardLibrary.getIterator(), JAVA_ITERATOR_TYPE); - register(standardLibrary.getMutableIterator(), JAVA_ITERATOR_TYPE); + register(JetStandardClasses.getAny(), Object.class); + register(standardLibrary.getNumber(), Number.class); + register(standardLibrary.getString(), String.class); + register(standardLibrary.getThrowable(), Throwable.class); + register(standardLibrary.getCharSequence(), CharSequence.class); + register(standardLibrary.getComparable(), Comparable.class); + register(standardLibrary.getEnum(), Enum.class); + register(standardLibrary.getAnnotation(), Annotation.class); + register(standardLibrary.getIterable(), Iterable.class); + register(standardLibrary.getIterator(), Iterator.class); + register(standardLibrary.getMutableIterable(), Iterable.class); + register(standardLibrary.getMutableIterator(), Iterator.class); + + register(standardLibrary.getCollection(), Collection.class); + register(standardLibrary.getMutableCollection(), Collection.class); + + register(standardLibrary.getList(), List.class); + register(standardLibrary.getMutableList(), List.class); + + register(standardLibrary.getSet(), Set.class); + register(standardLibrary.getMutableSet(), Set.class); + + register(standardLibrary.getMap(), Map.class); + register(standardLibrary.getMutableMap(), Map.class); + + register(standardLibrary.getMapEntry(), Map.Entry.class); + register(standardLibrary.getMutableMapEntry(), Map.Entry.class); + + register(standardLibrary.getListIterator(), ListIterator.class); + register(standardLibrary.getMutableListIterator(), ListIterator.class); } private void initPrimitives() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java index d75ab0343ca..55195bcacef 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java @@ -69,6 +69,24 @@ public class JavaToKotlinTypesMap { registerCovariant(Iterable.class, standardLibrary.getMutableIterable()); registerCovariant(Iterator.class, standardLibrary.getMutableIterator()); + + register(Collection.class, standardLibrary.getCollection()); + registerCovariant(Collection.class, standardLibrary.getMutableCollection()); + + register(List.class, standardLibrary.getList()); + registerCovariant(List.class, standardLibrary.getMutableList()); + + register(Set.class, standardLibrary.getSet()); + registerCovariant(Set.class, standardLibrary.getMutableSet()); + + register(Map.class, standardLibrary.getMap()); + registerCovariant(Map.class, standardLibrary.getMutableMap()); + + register(Map.Entry.class, standardLibrary.getMapEntry()); + registerCovariant(Map.Entry.class, standardLibrary.getMutableMapEntry()); + + register(ListIterator.class, standardLibrary.getListIterator()); + registerCovariant(ListIterator.class, standardLibrary.getMutableListIterator()); } private void initPrimitives() { @@ -95,7 +113,8 @@ public class JavaToKotlinTypesMap { @Nullable public ClassDescriptor getKotlinAnalog(@NotNull FqName fqName, @NotNull JavaTypeTransformer.TypeUsage typeUsage) { - if (typeUsage == JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_COVARIANT) { + if (typeUsage == JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_COVARIANT + || typeUsage == JavaTypeTransformer.TypeUsage.SUPERTYPE) { ClassDescriptor descriptor = classDescriptorMapForCovariantPositions.get(fqName); if (descriptor != null) { return descriptor; @@ -104,8 +123,12 @@ public class JavaToKotlinTypesMap { return classDescriptorMap.get(fqName); } + private static FqName getJavaClassFqName(@NotNull Class javaClass) { + return new FqName(javaClass.getName().replace("$", ".")); + } + private void register(@NotNull Class javaClass, @NotNull ClassDescriptor kotlinDescriptor) { - register(new FqName(javaClass.getName()), kotlinDescriptor); + register(getJavaClassFqName(javaClass), kotlinDescriptor); } private void register(@NotNull FqName javaClassName, @NotNull ClassDescriptor kotlinDescriptor) { @@ -114,7 +137,7 @@ public class JavaToKotlinTypesMap { } private void registerCovariant(@NotNull Class javaClass, @NotNull ClassDescriptor kotlinDescriptor) { - registerCovariant(new FqName(javaClass.getName()), kotlinDescriptor); + registerCovariant(getJavaClassFqName(javaClass), kotlinDescriptor); } private void registerCovariant(@NotNull FqName javaClassName, @NotNull ClassDescriptor kotlinDescriptor) { diff --git a/compiler/frontend/src/jet/Collections.jet b/compiler/frontend/src/jet/Collections.jet new file mode 100644 index 00000000000..0da8ea15783 --- /dev/null +++ b/compiler/frontend/src/jet/Collections.jet @@ -0,0 +1,140 @@ +package jet + +public trait Collection : Iterable, Hashable { + // Query Operations + public fun size() : Int + public fun isEmpty() : Boolean + public fun contains(o : Any?) : Boolean + override fun iterator() : Iterator + public fun toArray() : Array + public fun toArray(a : Array) : Array + + // Bulk Operations + public fun containsAll(c : Collection) : Boolean +} + +public trait MutableCollection : Collection, MutableIterable { + // Query Operations + override fun iterator() : MutableIterator + + // Modification Operations + public fun add(e : E) : Boolean + public fun remove(o : Any?) : Boolean + + // Bulk Modification Operations + public fun addAll(c : Collection) : Boolean + public fun removeAll(c : Collection) : Boolean + public fun retainAll(c : Collection) : Boolean + public fun clear() +} + +public trait List : Collection { + // Query Operations + override fun size() : Int + override fun isEmpty() : Boolean + override fun contains(o : Any?) : Boolean + override fun iterator() : Iterator + override fun toArray() : Array + override fun toArray(a : Array) : Array + + // Bulk Operations + override fun containsAll(c : Collection) : Boolean + + // Positional Access Operations + public fun get(index : Int) : E + + // Search Operations + public fun indexOf(o : Any?) : Int + public fun lastIndexOf(o : Any?) : Int + + // List Iterators + public fun listIterator() : ListIterator + public fun listIterator(index : Int) : ListIterator + + // View + public fun subList(fromIndex : Int, toIndex : Int) : List +} + +public trait MutableList : List, MutableCollection { + // Modification Operations + override fun add(e: E) : Boolean + override fun remove(o : Any?) : Boolean + + // Bulk Modification Operations + override fun addAll(c : Collection) : Boolean + public fun addAll(index : Int, c : Collection) : Boolean + override fun removeAll(c : Collection) : Boolean + override fun retainAll(c : Collection) : Boolean + override fun clear() + + // Positional Access Operations + public fun set(index : Int, element : E) : E + public fun add(index : Int, element : E) + public fun remove(index : Int) : E +} + +public trait Set : Collection { + // Query Operations + override fun size() : Int + override fun isEmpty() : Boolean + override fun contains(o : Any?) : Boolean + override fun iterator() : Iterator + override fun toArray() : Array + override fun toArray(a : Array) : Array + + // Bulk Operations + override fun containsAll(c : Collection) : Boolean +} + +public trait MutableSet : Set, MutableCollection { + // Query Operations + override fun iterator() : MutableIterator + + // Modification Operations + override fun add(e: E) : Boolean + override fun remove(o : Any?) : Boolean + + // Bulk Modification Operations + override fun addAll(c : Collection) : Boolean + override fun removeAll(c : Collection) : Boolean + override fun retainAll(c : Collection) : Boolean + override fun clear() +} + +public trait Map { + // Query Operations + public fun size() : Int + public fun isEmpty() : Boolean + public fun containsKey(key : Any?) : Boolean + public fun containsValue(value : Any?) : Boolean + public fun get(key : Any?) : V? + + // Views + public fun keySet() : Set + public fun values() : Collection + public fun entrySet() : Set> + + public trait Entry : Hashable { + public fun getKey() : K + public fun getValue() : V + } +} + +public trait MutableMap : Map { + // Modification Operations + public fun put(key : K, value : V) : V? + public fun remove(key : Any?) : V? + + // Bulk Modification Operations + public fun putAll(m : Map) + public fun clear() + + // Views + override fun keySet() : MutableSet + override fun values() : MutableCollection + override fun entrySet() : MutableSet> + + public trait MutableEntry : Map.Entry, Hashable { + public fun setValue(value : V) : V + } +} \ No newline at end of file diff --git a/compiler/frontend/src/jet/Iterators.jet b/compiler/frontend/src/jet/Iterators.jet index 717504c7132..5bddeeea7c4 100644 --- a/compiler/frontend/src/jet/Iterators.jet +++ b/compiler/frontend/src/jet/Iterators.jet @@ -75,3 +75,24 @@ public fun FloatIterator.iterator() : FloatIterator public fun LongIterator.iterator() : LongIterator +public trait ListIterator : Iterator { + // Query Operations + override fun hasNext() : Boolean + override fun next() : T + + public fun hasPrevious() : Boolean + public fun previous() : T + public fun nextIndex() : Int + public fun previousIndex() : Int +} + +public trait MutableListIterator : ListIterator, MutableIterator { + // Query Operations + override fun hasNext() : Boolean + override fun next() : T + + // Modification Operations + override fun remove() + public fun set(e : T) + public fun add(e : T) +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java index 1c381ef5faa..30ffa7cb81a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardLibrary.java @@ -24,6 +24,7 @@ import com.intellij.psi.PsiFileFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -119,7 +120,8 @@ public class JetStandardLibrary { "Iterables.jet", "Iterators.jet", "Arrays.jet", - "Enum.jet" + "Enum.jet", + "Collections.jet" ); try { List files = new LinkedList(); @@ -371,6 +373,70 @@ public class JetStandardLibrary { return annotationType; } + @NotNull + public ClassDescriptor getCollection() { + return getStdClassByName("Collection"); + } + + @NotNull + public ClassDescriptor getMutableCollection() { + return getStdClassByName("MutableCollection"); + } + + @NotNull + public ClassDescriptor getList() { + return getStdClassByName("List"); + } + + @NotNull + public ClassDescriptor getMutableList() { + return getStdClassByName("MutableList"); + } + + @NotNull + public ClassDescriptor getListIterator() { + return getStdClassByName("ListIterator"); + } + + @NotNull + public ClassDescriptor getMutableListIterator() { + return getStdClassByName("MutableListIterator"); + } + + @NotNull + public ClassDescriptor getSet() { + return getStdClassByName("Set"); + } + + @NotNull + public ClassDescriptor getMutableSet() { + return getStdClassByName("MutableSet"); + } + + @NotNull + public ClassDescriptor getMap() { + return getStdClassByName("Map"); + } + + @NotNull + public ClassDescriptor getMutableMap() { + return getStdClassByName("MutableMap"); + } + + @NotNull + public ClassDescriptor getMapEntry() { + ClassifierDescriptor entry = getMap().getDefaultType().getMemberScope().getClassifier(Name.identifier("Entry")); + assert entry instanceof ClassDescriptor; + return (ClassDescriptor) entry; + } + + @NotNull + public ClassDescriptor getMutableMapEntry() { + ClassifierDescriptor entry = getMutableMap().getDefaultType().getMemberScope().getClassifier(Name.identifier("MutableEntry")); + assert entry instanceof ClassDescriptor; + return (ClassDescriptor) entry; + } + @NotNull public JetType getPrimitiveJetType(PrimitiveType primitiveType) { return primitiveTypeToJetType.get(primitiveType);