Supported propagation for subclass of j.u.Collection and similar classes.
This commit is contained in:
+149
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.*;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class JavaToKotlinMethodMap {
|
||||
public static final JavaToKotlinMethodMap INSTANCE = new JavaToKotlinMethodMap();
|
||||
|
||||
private final JavaToKotlinMethodMapGenerated mapContainer = new JavaToKotlinMethodMapGenerated();
|
||||
|
||||
private JavaToKotlinMethodMap() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<ClassDescriptor> getAllSuperClasses(@NotNull ClassDescriptor klass) {
|
||||
Set<JetType> allSupertypes = TypeUtils.getAllSupertypes(klass.getDefaultType());
|
||||
Set<ClassDescriptor> allSuperclasses = Sets.newHashSet();
|
||||
for (JetType supertype : allSupertypes) {
|
||||
ClassDescriptor superclass = TypeUtils.getClassDescriptor(supertype);
|
||||
assert superclass != null;
|
||||
allSuperclasses.add(superclass);
|
||||
}
|
||||
return allSuperclasses;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<FunctionDescriptor> getFunctions(@NotNull PsiMethod psiMethod, @NotNull ClassDescriptor containingClass) {
|
||||
ImmutableCollection<ClassData> classDatas = mapContainer.map.get(psiMethod.getContainingClass().getQualifiedName());
|
||||
|
||||
List<FunctionDescriptor> result = Lists.newArrayList();
|
||||
|
||||
Set<ClassDescriptor> allSuperClasses = getAllSuperClasses(containingClass);
|
||||
|
||||
String serializedPsiMethod = serializePsiMethod(psiMethod);
|
||||
for (ClassData classData : classDatas) {
|
||||
String expectedSerializedFunction = classData.method2Function.get(serializedPsiMethod);
|
||||
if (expectedSerializedFunction == null) continue;
|
||||
|
||||
ClassDescriptor kotlinClass = classData.kotlinClass;
|
||||
if (!allSuperClasses.contains(kotlinClass)) continue;
|
||||
|
||||
|
||||
Collection<FunctionDescriptor> functions =
|
||||
kotlinClass.getDefaultType().getMemberScope().getFunctions(Name.identifier(psiMethod.getName()));
|
||||
|
||||
for (FunctionDescriptor function : functions) {
|
||||
if (expectedSerializedFunction.equals(serializeFunction(function))) {
|
||||
result.add(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String serializePsiMethod(@NotNull PsiMethod psiMethod) {
|
||||
String externalName = PsiFormatUtil.getExternalName(psiMethod);
|
||||
assert externalName != null : "couldn't find external name for " + psiMethod.getText();
|
||||
return externalName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String serializeFunction(@NotNull FunctionDescriptor fun) {
|
||||
return DescriptorRenderer.TEXT.render(fun);
|
||||
}
|
||||
|
||||
// used in generated code
|
||||
static Pair<String, String> pair(String a, String b) {
|
||||
return Pair.create(a, b);
|
||||
}
|
||||
|
||||
// used in generated code
|
||||
static void put(
|
||||
ImmutableMultimap.Builder<String, ClassData> builder,
|
||||
String javaFqName,
|
||||
String kotlinQualifiedName,
|
||||
Pair<String, String>... methods2Functions
|
||||
) {
|
||||
ImmutableMap<String, String> methods2FunctionsMap = pairs2Map(methods2Functions);
|
||||
|
||||
ClassDescriptor kotlinClass;
|
||||
if (kotlinQualifiedName.contains(".")) { // Map.Entry and MutableMap.MutableEntry
|
||||
String[] kotlinNames = kotlinQualifiedName.split("\\.");
|
||||
assert kotlinNames.length == 2 : "unexpected qualified name " + kotlinQualifiedName;
|
||||
|
||||
ClassDescriptor outerClass = KotlinBuiltIns.getInstance().getBuiltInClassByName(Name.identifier(kotlinNames[0]));
|
||||
kotlinClass = DescriptorUtils.getInnerClassByName(outerClass, kotlinNames[1]);
|
||||
assert kotlinClass != null : "Class not found: " + kotlinQualifiedName;
|
||||
}
|
||||
else {
|
||||
kotlinClass = KotlinBuiltIns.getInstance().getBuiltInClassByName(Name.identifier(kotlinQualifiedName));
|
||||
}
|
||||
|
||||
builder.put(javaFqName, new ClassData(kotlinClass, methods2FunctionsMap));
|
||||
}
|
||||
|
||||
private static ImmutableMap<String, String> pairs2Map(Pair<String, String>[] pairs) {
|
||||
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||
for (Pair<String, String> pair : pairs) {
|
||||
builder.put(pair.first, pair.second);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static class ClassData {
|
||||
@NotNull
|
||||
public final ClassDescriptor kotlinClass;
|
||||
@NotNull
|
||||
public Map<String, String> method2Function;
|
||||
|
||||
public ClassData(@NotNull ClassDescriptor kotlinClass, @NotNull Map<String, String> method2Function) {
|
||||
this.kotlinClass = kotlinClass;
|
||||
this.method2Function = method2Function;
|
||||
}
|
||||
}
|
||||
}
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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.ImmutableMultimap;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.JavaToKotlinMethodMap.*;
|
||||
|
||||
/* This file is generated by org.jetbrains.jet.generators.GenerateJavaToKotlinMethodMap. DO NOT EDIT! */
|
||||
@SuppressWarnings("unchecked")
|
||||
class JavaToKotlinMethodMapGenerated {
|
||||
final ImmutableMultimap<String, JavaToKotlinMethodMap.ClassData> map;
|
||||
|
||||
JavaToKotlinMethodMapGenerated() {
|
||||
ImmutableMultimap.Builder<String, JavaToKotlinMethodMap.ClassData> b = ImmutableMultimap.builder();
|
||||
|
||||
put(b, "java.lang.String", "String",
|
||||
pair("java.lang.String int compareTo(java.lang.String)", "public open fun compareTo(that : jet.String) : jet.Int defined in jet.String"),
|
||||
pair("java.lang.String boolean equals(java.lang.Object)", "public final fun equals(other : jet.Any?) : jet.Boolean defined in jet.String"),
|
||||
pair("java.lang.String java.lang.String toString()", "public open fun toString() : jet.String defined in jet.String")
|
||||
);
|
||||
|
||||
put(b, "java.lang.CharSequence", "CharSequence",
|
||||
pair("java.lang.CharSequence java.lang.String toString()", "public abstract fun toString() : jet.String defined in jet.CharSequence")
|
||||
);
|
||||
|
||||
put(b, "java.lang.Throwable", "Throwable",
|
||||
pair("java.lang.Throwable java.lang.Throwable getCause()", "public final fun getCause() : jet.Throwable? defined in jet.Throwable"),
|
||||
pair("java.lang.Throwable java.lang.String getMessage()", "public final fun getMessage() : jet.String? defined in jet.Throwable"),
|
||||
pair("java.lang.Throwable void printStackTrace()", "public final fun printStackTrace() : Unit defined in jet.Throwable")
|
||||
);
|
||||
|
||||
put(b, "java.lang.Comparable", "Comparable",
|
||||
pair("java.lang.Comparable int compareTo(T)", "public abstract fun compareTo(other : T) : jet.Int defined in jet.Comparable")
|
||||
);
|
||||
|
||||
put(b, "java.lang.Enum", "Enum",
|
||||
pair("java.lang.Enum java.lang.String name()", "public final fun name() : jet.String defined in jet.Enum"),
|
||||
pair("java.lang.Enum int ordinal()", "public final fun ordinal() : jet.Int defined in jet.Enum")
|
||||
);
|
||||
|
||||
put(b, "java.lang.Iterable", "Iterable",
|
||||
pair("java.lang.Iterable java.util.Iterator<T> iterator()", "public abstract fun iterator() : jet.Iterator<T> defined in jet.Iterable")
|
||||
);
|
||||
|
||||
put(b, "java.lang.Iterable", "MutableIterable",
|
||||
pair("java.lang.Iterable java.util.Iterator<T> iterator()", "public abstract fun iterator() : jet.MutableIterator<T> defined in jet.MutableIterable")
|
||||
);
|
||||
|
||||
put(b, "java.util.Iterator", "Iterator",
|
||||
pair("java.util.Iterator boolean hasNext()", "public abstract fun hasNext() : jet.Boolean defined in jet.Iterator"),
|
||||
pair("java.util.Iterator E next()", "public abstract fun next() : T defined in jet.Iterator")
|
||||
);
|
||||
|
||||
put(b, "java.util.Iterator", "MutableIterator",
|
||||
pair("java.util.Iterator boolean hasNext()", "public abstract fun hasNext() : jet.Boolean defined in jet.MutableIterator"),
|
||||
pair("java.util.Iterator E next()", "public abstract fun next() : T defined in jet.MutableIterator"),
|
||||
pair("java.util.Iterator void remove()", "public abstract fun remove() : Unit defined in jet.MutableIterator")
|
||||
);
|
||||
|
||||
put(b, "java.util.Collection", "Collection",
|
||||
pair("java.util.Collection boolean contains(java.lang.Object)", "public abstract fun contains(o : jet.Any?) : jet.Boolean defined in jet.Collection"),
|
||||
pair("java.util.Collection boolean containsAll(java.util.Collection<?>)", "public abstract fun containsAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.Collection"),
|
||||
pair("java.util.Collection boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.Collection"),
|
||||
pair("java.util.Collection int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.Collection"),
|
||||
pair("java.util.Collection boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.Collection"),
|
||||
pair("java.util.Collection java.util.Iterator<E> iterator()", "public abstract fun iterator() : jet.Iterator<E> defined in jet.Collection"),
|
||||
pair("java.util.Collection int size()", "public abstract fun size() : jet.Int defined in jet.Collection"),
|
||||
pair("java.util.Collection T[] toArray(T[])", "public abstract fun <T> toArray(a : jet.Array<out T>) : jet.Array<T> defined in jet.Collection"),
|
||||
pair("java.util.Collection java.lang.Object[] toArray()", "public abstract fun toArray() : jet.Array<jet.Any?> defined in jet.Collection")
|
||||
);
|
||||
|
||||
put(b, "java.util.Collection", "MutableCollection",
|
||||
pair("java.util.Collection boolean add(E)", "public abstract fun add(e : E) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean addAll(java.util.Collection<? extends E>)", "public abstract fun addAll(c : jet.Collection<E>) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection void clear()", "public abstract fun clear() : Unit defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean contains(java.lang.Object)", "public abstract fun contains(o : jet.Any?) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean containsAll(java.util.Collection<?>)", "public abstract fun containsAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection java.util.Iterator<E> iterator()", "public abstract fun iterator() : jet.MutableIterator<E> defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean remove(java.lang.Object)", "public abstract fun remove(o : jet.Any?) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean removeAll(java.util.Collection<?>)", "public abstract fun removeAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection boolean retainAll(java.util.Collection<?>)", "public abstract fun retainAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection int size()", "public abstract fun size() : jet.Int defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection T[] toArray(T[])", "public abstract fun <T> toArray(a : jet.Array<out T>) : jet.Array<T> defined in jet.MutableCollection"),
|
||||
pair("java.util.Collection java.lang.Object[] toArray()", "public abstract fun toArray() : jet.Array<jet.Any?> defined in jet.MutableCollection")
|
||||
);
|
||||
|
||||
put(b, "java.util.List", "List",
|
||||
pair("java.util.List boolean contains(java.lang.Object)", "public abstract fun contains(o : jet.Any?) : jet.Boolean defined in jet.List"),
|
||||
pair("java.util.List boolean containsAll(java.util.Collection<?>)", "public abstract fun containsAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.List"),
|
||||
pair("java.util.List boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.List"),
|
||||
pair("java.util.List E get(int)", "public abstract fun get(index : jet.Int) : E defined in jet.List"),
|
||||
pair("java.util.List int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.List"),
|
||||
pair("java.util.List int indexOf(java.lang.Object)", "public abstract fun indexOf(o : jet.Any?) : jet.Int defined in jet.List"),
|
||||
pair("java.util.List boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.List"),
|
||||
pair("java.util.List java.util.Iterator<E> iterator()", "public abstract fun iterator() : jet.Iterator<E> defined in jet.List"),
|
||||
pair("java.util.List int lastIndexOf(java.lang.Object)", "public abstract fun lastIndexOf(o : jet.Any?) : jet.Int defined in jet.List"),
|
||||
pair("java.util.List java.util.ListIterator<E> listIterator()", "public abstract fun listIterator() : jet.ListIterator<E> defined in jet.List"),
|
||||
pair("java.util.List java.util.ListIterator<E> listIterator(int)", "public abstract fun listIterator(index : jet.Int) : jet.ListIterator<E> defined in jet.List"),
|
||||
pair("java.util.List int size()", "public abstract fun size() : jet.Int defined in jet.List"),
|
||||
pair("java.util.List java.util.List<E> subList(int, int)", "public abstract fun subList(fromIndex : jet.Int, toIndex : jet.Int) : jet.List<E> defined in jet.List"),
|
||||
pair("java.util.List T[] toArray(T[])", "public abstract fun <T> toArray(a : jet.Array<out T>) : jet.Array<T> defined in jet.List"),
|
||||
pair("java.util.List java.lang.Object[] toArray()", "public abstract fun toArray() : jet.Array<jet.Any?> defined in jet.List")
|
||||
);
|
||||
|
||||
put(b, "java.util.List", "MutableList",
|
||||
pair("java.util.List boolean add(E)", "public abstract fun add(e : E) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List void add(int, E)", "public abstract fun add(index : jet.Int, element : E) : Unit defined in jet.MutableList"),
|
||||
pair("java.util.List boolean addAll(int, java.util.Collection<? extends E>)", "public abstract fun addAll(index : jet.Int, c : jet.Collection<E>) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List boolean addAll(java.util.Collection<? extends E>)", "public abstract fun addAll(c : jet.Collection<E>) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List void clear()", "public abstract fun clear() : Unit defined in jet.MutableList"),
|
||||
pair("java.util.List boolean contains(java.lang.Object)", "public abstract fun contains(o : jet.Any?) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List boolean containsAll(java.util.Collection<?>)", "public abstract fun containsAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List E get(int)", "public abstract fun get(index : jet.Int) : E defined in jet.MutableList"),
|
||||
pair("java.util.List int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.MutableList"),
|
||||
pair("java.util.List int indexOf(java.lang.Object)", "public abstract fun indexOf(o : jet.Any?) : jet.Int defined in jet.MutableList"),
|
||||
pair("java.util.List boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List java.util.Iterator<E> iterator()", "public abstract fun iterator() : jet.Iterator<E> defined in jet.MutableList"),
|
||||
pair("java.util.List int lastIndexOf(java.lang.Object)", "public abstract fun lastIndexOf(o : jet.Any?) : jet.Int defined in jet.MutableList"),
|
||||
pair("java.util.List java.util.ListIterator<E> listIterator()", "public abstract fun listIterator() : jet.MutableListIterator<E> defined in jet.MutableList"),
|
||||
pair("java.util.List java.util.ListIterator<E> listIterator(int)", "public abstract fun listIterator(index : jet.Int) : jet.MutableListIterator<E> defined in jet.MutableList"),
|
||||
pair("java.util.List E remove(int)", "public abstract fun remove(index : jet.Int) : E defined in jet.MutableList"),
|
||||
pair("java.util.List boolean remove(java.lang.Object)", "public abstract fun remove(o : jet.Any?) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List boolean removeAll(java.util.Collection<?>)", "public abstract fun removeAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List boolean retainAll(java.util.Collection<?>)", "public abstract fun retainAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableList"),
|
||||
pair("java.util.List E set(int, E)", "public abstract fun set(index : jet.Int, element : E) : E defined in jet.MutableList"),
|
||||
pair("java.util.List int size()", "public abstract fun size() : jet.Int defined in jet.MutableList"),
|
||||
pair("java.util.List java.util.List<E> subList(int, int)", "public abstract fun subList(fromIndex : jet.Int, toIndex : jet.Int) : jet.MutableList<E> defined in jet.MutableList"),
|
||||
pair("java.util.List T[] toArray(T[])", "public abstract fun <T> toArray(a : jet.Array<out T>) : jet.Array<T> defined in jet.MutableList"),
|
||||
pair("java.util.List java.lang.Object[] toArray()", "public abstract fun toArray() : jet.Array<jet.Any?> defined in jet.MutableList")
|
||||
);
|
||||
|
||||
put(b, "java.util.Set", "Set",
|
||||
pair("java.util.Set boolean contains(java.lang.Object)", "public abstract fun contains(o : jet.Any?) : jet.Boolean defined in jet.Set"),
|
||||
pair("java.util.Set boolean containsAll(java.util.Collection<?>)", "public abstract fun containsAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.Set"),
|
||||
pair("java.util.Set boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.Set"),
|
||||
pair("java.util.Set int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.Set"),
|
||||
pair("java.util.Set boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.Set"),
|
||||
pair("java.util.Set java.util.Iterator<E> iterator()", "public abstract fun iterator() : jet.Iterator<E> defined in jet.Set"),
|
||||
pair("java.util.Set int size()", "public abstract fun size() : jet.Int defined in jet.Set"),
|
||||
pair("java.util.Set T[] toArray(T[])", "public abstract fun <T> toArray(a : jet.Array<out T>) : jet.Array<T> defined in jet.Set"),
|
||||
pair("java.util.Set java.lang.Object[] toArray()", "public abstract fun toArray() : jet.Array<jet.Any?> defined in jet.Set")
|
||||
);
|
||||
|
||||
put(b, "java.util.Set", "MutableSet",
|
||||
pair("java.util.Set boolean add(E)", "public abstract fun add(e : E) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean addAll(java.util.Collection<? extends E>)", "public abstract fun addAll(c : jet.Collection<E>) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set void clear()", "public abstract fun clear() : Unit defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean contains(java.lang.Object)", "public abstract fun contains(o : jet.Any?) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean containsAll(java.util.Collection<?>)", "public abstract fun containsAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set java.util.Iterator<E> iterator()", "public abstract fun iterator() : jet.MutableIterator<E> defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean remove(java.lang.Object)", "public abstract fun remove(o : jet.Any?) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean removeAll(java.util.Collection<?>)", "public abstract fun removeAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set boolean retainAll(java.util.Collection<?>)", "public abstract fun retainAll(c : jet.Collection<jet.Any?>) : jet.Boolean defined in jet.MutableSet"),
|
||||
pair("java.util.Set int size()", "public abstract fun size() : jet.Int defined in jet.MutableSet"),
|
||||
pair("java.util.Set T[] toArray(T[])", "public abstract fun <T> toArray(a : jet.Array<out T>) : jet.Array<T> defined in jet.MutableSet"),
|
||||
pair("java.util.Set java.lang.Object[] toArray()", "public abstract fun toArray() : jet.Array<jet.Any?> defined in jet.MutableSet")
|
||||
);
|
||||
|
||||
put(b, "java.util.Map", "Map",
|
||||
pair("java.util.Map boolean containsKey(java.lang.Object)", "public abstract fun containsKey(key : jet.Any?) : jet.Boolean defined in jet.Map"),
|
||||
pair("java.util.Map boolean containsValue(java.lang.Object)", "public abstract fun containsValue(value : jet.Any?) : jet.Boolean defined in jet.Map"),
|
||||
pair("java.util.Map java.util.Set<java.util.Map.Entry<K,V>> entrySet()", "public abstract fun entrySet() : jet.Set<jet.Map.Entry<K, V>> defined in jet.Map"),
|
||||
pair("java.util.Map V get(java.lang.Object)", "public abstract fun get(key : jet.Any?) : V? defined in jet.Map"),
|
||||
pair("java.util.Map boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.Map"),
|
||||
pair("java.util.Map java.util.Set<K> keySet()", "public abstract fun keySet() : jet.Set<K> defined in jet.Map"),
|
||||
pair("java.util.Map int size()", "public abstract fun size() : jet.Int defined in jet.Map"),
|
||||
pair("java.util.Map java.util.Collection<V> values()", "public abstract fun values() : jet.Collection<V> defined in jet.Map")
|
||||
);
|
||||
|
||||
put(b, "java.util.Map", "MutableMap",
|
||||
pair("java.util.Map void clear()", "public abstract fun clear() : Unit defined in jet.MutableMap"),
|
||||
pair("java.util.Map boolean containsKey(java.lang.Object)", "public abstract fun containsKey(key : jet.Any?) : jet.Boolean defined in jet.MutableMap"),
|
||||
pair("java.util.Map boolean containsValue(java.lang.Object)", "public abstract fun containsValue(value : jet.Any?) : jet.Boolean defined in jet.MutableMap"),
|
||||
pair("java.util.Map java.util.Set<java.util.Map.Entry<K,V>> entrySet()", "public abstract fun entrySet() : jet.MutableSet<jet.MutableMap.MutableEntry<K, V>> defined in jet.MutableMap"),
|
||||
pair("java.util.Map V get(java.lang.Object)", "public abstract fun get(key : jet.Any?) : V? defined in jet.MutableMap"),
|
||||
pair("java.util.Map boolean isEmpty()", "public abstract fun isEmpty() : jet.Boolean defined in jet.MutableMap"),
|
||||
pair("java.util.Map java.util.Set<K> keySet()", "public abstract fun keySet() : jet.MutableSet<K> defined in jet.MutableMap"),
|
||||
pair("java.util.Map V put(K, V)", "public abstract fun put(key : K, value : V) : V? defined in jet.MutableMap"),
|
||||
pair("java.util.Map void putAll(java.util.Map<? extends K,? extends V>)", "public abstract fun putAll(m : jet.Map<out K, out V>) : Unit defined in jet.MutableMap"),
|
||||
pair("java.util.Map V remove(java.lang.Object)", "public abstract fun remove(key : jet.Any?) : V? defined in jet.MutableMap"),
|
||||
pair("java.util.Map int size()", "public abstract fun size() : jet.Int defined in jet.MutableMap"),
|
||||
pair("java.util.Map java.util.Collection<V> values()", "public abstract fun values() : jet.MutableCollection<V> defined in jet.MutableMap")
|
||||
);
|
||||
|
||||
put(b, "java.util.Map.Entry", "Map.Entry",
|
||||
pair("java.util.Map.Entry boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.Map.Entry"),
|
||||
pair("java.util.Map.Entry K getKey()", "public abstract fun getKey() : K defined in jet.Map.Entry"),
|
||||
pair("java.util.Map.Entry V getValue()", "public abstract fun getValue() : V defined in jet.Map.Entry"),
|
||||
pair("java.util.Map.Entry int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.Map.Entry")
|
||||
);
|
||||
|
||||
put(b, "java.util.Map.Entry", "MutableMap.MutableEntry",
|
||||
pair("java.util.Map.Entry boolean equals(java.lang.Object)", "public abstract fun equals(other : jet.Any?) : jet.Boolean defined in jet.MutableMap.MutableEntry"),
|
||||
pair("java.util.Map.Entry K getKey()", "public abstract fun getKey() : K defined in jet.MutableMap.MutableEntry"),
|
||||
pair("java.util.Map.Entry V getValue()", "public abstract fun getValue() : V defined in jet.MutableMap.MutableEntry"),
|
||||
pair("java.util.Map.Entry int hashCode()", "public abstract fun hashCode() : jet.Int defined in jet.MutableMap.MutableEntry"),
|
||||
pair("java.util.Map.Entry V setValue(V)", "public abstract fun setValue(value : V) : V defined in jet.MutableMap.MutableEntry")
|
||||
);
|
||||
|
||||
put(b, "java.util.ListIterator", "ListIterator",
|
||||
pair("java.util.ListIterator boolean hasNext()", "public abstract fun hasNext() : jet.Boolean defined in jet.ListIterator"),
|
||||
pair("java.util.ListIterator boolean hasPrevious()", "public abstract fun hasPrevious() : jet.Boolean defined in jet.ListIterator"),
|
||||
pair("java.util.ListIterator E next()", "public abstract fun next() : T defined in jet.ListIterator"),
|
||||
pair("java.util.ListIterator int nextIndex()", "public abstract fun nextIndex() : jet.Int defined in jet.ListIterator"),
|
||||
pair("java.util.ListIterator E previous()", "public abstract fun previous() : T defined in jet.ListIterator"),
|
||||
pair("java.util.ListIterator int previousIndex()", "public abstract fun previousIndex() : jet.Int defined in jet.ListIterator")
|
||||
);
|
||||
|
||||
put(b, "java.util.ListIterator", "MutableListIterator",
|
||||
pair("java.util.ListIterator void add(E)", "public abstract fun add(e : T) : Unit defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator boolean hasNext()", "public abstract fun hasNext() : jet.Boolean defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator boolean hasPrevious()", "public abstract fun hasPrevious() : jet.Boolean defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator E next()", "public abstract fun next() : T defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator int nextIndex()", "public abstract fun nextIndex() : jet.Int defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator E previous()", "public abstract fun previous() : T defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator int previousIndex()", "public abstract fun previousIndex() : jet.Int defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator void remove()", "public abstract fun remove() : Unit defined in jet.MutableListIterator"),
|
||||
pair("java.util.ListIterator void set(E)", "public abstract fun set(e : T) : Unit defined in jet.MutableListIterator")
|
||||
);
|
||||
|
||||
map = b.build();
|
||||
}
|
||||
}
|
||||
+22
-10
@@ -28,7 +28,10 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.java.CollectionClassMapping;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaToKotlinClassMap;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaToKotlinMethodMap;
|
||||
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
@@ -50,13 +53,14 @@ public class SignaturesPropagationData {
|
||||
private final Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> autoTypeParameterToModified;
|
||||
|
||||
public SignaturesPropagationData(
|
||||
@NotNull ClassDescriptor containingClass,
|
||||
@NotNull JetType autoReturnType, // type built by JavaTypeTransformer from Java signature and @NotNull annotations
|
||||
@NotNull JavaDescriptorResolver.ValueParameterDescriptors autoValueParameters, // descriptors built by parameters resolver
|
||||
@NotNull List<TypeParameterDescriptor> autoTypeParameters, // descriptors built by signature resolver
|
||||
@NotNull PsiMethodWrapper method,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
superFunctions = getSuperFunctionsForMethod(method, trace);
|
||||
superFunctions = getSuperFunctionsForMethod(method, trace, containingClass);
|
||||
|
||||
autoTypeParameterToModified = SignaturesUtil.recreateTypeParametersAndReturnMapping(autoTypeParameters);
|
||||
|
||||
@@ -187,7 +191,8 @@ public class SignaturesPropagationData {
|
||||
|
||||
private static List<FunctionDescriptor> getSuperFunctionsForMethod(
|
||||
@NotNull PsiMethodWrapper method,
|
||||
@NotNull BindingTrace trace
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull ClassDescriptor containingClass
|
||||
) {
|
||||
List<FunctionDescriptor> superFunctions = Lists.newArrayList();
|
||||
for (HierarchicalMethodSignature superSignature : method.getPsiMethod().getHierarchicalMethodSignature().getSuperSignatures()) {
|
||||
@@ -196,15 +201,22 @@ public class SignaturesPropagationData {
|
||||
superFunctions.add(((FunctionDescriptor) superFun));
|
||||
}
|
||||
else {
|
||||
// TODO assert is temporarily disabled
|
||||
// It fails because of bug in IDEA on Mac: it adds invalid roots to JDK classpath and it leads to the problem that
|
||||
// getHierarchicalMethodSignature() returns elements from invalid virtual files
|
||||
String fqName = superSignature.getMethod().getContainingClass().getQualifiedName();
|
||||
assert fqName != null;
|
||||
Collection<ClassDescriptor> platformClasses = JavaToKotlinClassMap.getInstance().mapPlatformClass(new FqName(fqName));
|
||||
if (platformClasses.isEmpty()) {
|
||||
// TODO assert is temporarily disabled
|
||||
// It fails because of bug in IDEA on Mac: it adds invalid roots to JDK classpath and it leads to the problem that
|
||||
// getHierarchicalMethodSignature() returns elements from invalid virtual files
|
||||
|
||||
// Function descriptor can't be find iff superclass is java.lang.Collection or similar (translated to jet.* collections)
|
||||
//assert !JavaToKotlinClassMap.getInstance().mapPlatformClass(
|
||||
// new FqName(superSignature.getMethod().getContainingClass().getQualifiedName())).isEmpty():
|
||||
// "Can't find super function for " + method.getPsiMethod() + " defined in "
|
||||
// + method.getPsiMethod().getContainingClass();
|
||||
//assert false : "Can't find super function for " + method.getPsiMethod() +
|
||||
// " defined in " + method.getPsiMethod().getContainingClass()
|
||||
}
|
||||
else {
|
||||
List<FunctionDescriptor> funsFromMap =
|
||||
JavaToKotlinMethodMap.INSTANCE.getFunctions(superSignature.getMethod(), containingClass);
|
||||
superFunctions.addAll(funsFromMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -144,8 +144,8 @@ public final class JavaFunctionResolver {
|
||||
|
||||
List<FunctionDescriptor> superFunctions;
|
||||
if (ownerDescriptor instanceof ClassDescriptor) {
|
||||
SignaturesPropagationData signaturesPropagationData =
|
||||
new SignaturesPropagationData(returnType, valueParameterDescriptors, methodTypeParameters, method, trace);
|
||||
SignaturesPropagationData signaturesPropagationData = new SignaturesPropagationData(
|
||||
(ClassDescriptor) ownerDescriptor, returnType, valueParameterDescriptors, methodTypeParameters, method, trace);
|
||||
superFunctions = signaturesPropagationData.getSuperFunctions();
|
||||
|
||||
returnType = signaturesPropagationData.getModifiedReturnType();
|
||||
@@ -214,6 +214,9 @@ public final class JavaFunctionResolver {
|
||||
((ClassDescriptor) functionDescriptor.getContainingDeclaration()).getDefaultType());
|
||||
FunctionDescriptor superFunctionSubstituted = superFunction.substitute(substitutor);
|
||||
|
||||
assert superFunctionSubstituted != null :
|
||||
"Couldn't substitute super function: " + superFunction + ", substitutor = " + substitutor;
|
||||
|
||||
OverrideCompatibilityInfo.Result overridableResult =
|
||||
isOverridableBy(superFunctionSubstituted, functionDescriptor).getResult();
|
||||
boolean paramsOk = overridableResult == OverrideCompatibilityInfo.Result.OVERRIDABLE;
|
||||
|
||||
@@ -334,12 +334,17 @@ public class KotlinBuiltIns {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@NotNull
|
||||
private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) {
|
||||
ClassifierDescriptor classifier = getBuiltInsScope().getClassifier(Name.identifier(simpleName));
|
||||
public ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName) {
|
||||
ClassifierDescriptor classifier = getBuiltInsScope().getClassifier(simpleName);
|
||||
assert classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " + classifier;
|
||||
return (ClassDescriptor) classifier;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) {
|
||||
return getBuiltInClassByName(Name.identifier(simpleName));
|
||||
}
|
||||
|
||||
// Special
|
||||
|
||||
@NotNull
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface SubclassOfCollection<E> extends Collection<E> {
|
||||
Iterator<E> iterator();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
public trait SubclassOfCollection<E>: MutableCollection<E> {
|
||||
override fun iterator() : MutableIterator<E>
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
namespace test
|
||||
|
||||
public abstract trait test.SubclassOfCollection</*0*/ E : jet.Any?> : jet.MutableCollection<E> {
|
||||
public abstract override /*1*/ /*fake_override*/ fun add(/*0*/ e: E): jet.Boolean
|
||||
public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: jet.Collection<E>): jet.Boolean
|
||||
public abstract override /*1*/ /*fake_override*/ fun clear(): jet.Tuple0
|
||||
public abstract override /*1*/ /*fake_override*/ fun contains(/*0*/ o: jet.Any?): jet.Boolean
|
||||
public abstract override /*1*/ /*fake_override*/ fun containsAll(/*0*/ c: jet.Collection<jet.Any?>): jet.Boolean
|
||||
public abstract override /*1*/ /*fake_override*/ fun isEmpty(): jet.Boolean
|
||||
public abstract override /*1*/ fun iterator(): jet.MutableIterator<E>
|
||||
public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: jet.Any?): jet.Boolean
|
||||
public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: jet.Collection<jet.Any?>): jet.Boolean
|
||||
public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: jet.Collection<jet.Any?>): jet.Boolean
|
||||
public abstract override /*1*/ /*fake_override*/ fun size(): jet.Int
|
||||
public abstract override /*1*/ /*fake_override*/ fun toArray(): jet.Array<jet.Any?>
|
||||
public abstract override /*1*/ /*fake_override*/ fun </*0*/ T : jet.Any?>toArray(/*0*/ a: jet.Array<out T>): jet.Array<T>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface SubclassOfMapEntry<K, V> extends Map.Entry<K, V> {
|
||||
V setValue(V v);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
public trait SubclassOfMapEntry<K, V>: MutableMap.MutableEntry<K, V> {
|
||||
override fun setValue(p0: V) : V
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace test
|
||||
|
||||
public abstract trait test.SubclassOfMapEntry</*0*/ K : jet.Any?, /*1*/ V : jet.Any?> : jet.MutableMap.MutableEntry<K, V> {
|
||||
public abstract override /*1*/ /*fake_override*/ fun getKey(): K
|
||||
public abstract override /*1*/ /*fake_override*/ fun getValue(): V
|
||||
public abstract override /*1*/ fun setValue(/*0*/ p0: V): V
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public open class test.ModalityOfFakeOverrides : java.util.AbstractList<jet.Stri
|
||||
public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ p0: jet.Int): jet.MutableListIterator<jet.String>
|
||||
protected final override /*1*/ /*fake_override*/ var modCount: jet.Int
|
||||
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ p0: jet.Any?): jet.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ p0: jet.Int): jet.String?
|
||||
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ p0: jet.Int): jet.String
|
||||
public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ p0: jet.Collection<jet.Any?>): jet.Boolean
|
||||
protected open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: jet.Int, /*1*/ p1: jet.Int): jet.Tuple0
|
||||
public open override /*1*/ /*fake_override*/ fun retainAll(/*0*/ p0: jet.Collection<jet.Any?>): jet.Boolean
|
||||
|
||||
@@ -649,6 +649,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/SameProjectionKind.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SubclassOfCollection.java")
|
||||
public void testSubclassOfCollection() throws Exception {
|
||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/SubclassOfCollection.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SubclassOfMapEntry.java")
|
||||
public void testSubclassOfMapEntry() throws Exception {
|
||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/SubclassOfMapEntry.java");
|
||||
}
|
||||
|
||||
@TestMetadata("TwoSuperclassesConflictingProjectionKinds.java")
|
||||
public void testTwoSuperclassesConflictingProjectionKinds() throws Exception {
|
||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesConflictingProjectionKinds.java");
|
||||
|
||||
+10
@@ -1539,6 +1539,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/SameProjectionKind.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SubclassOfCollection.kt")
|
||||
public void testSubclassOfCollection() throws Exception {
|
||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/SubclassOfCollection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SubclassOfMapEntry.kt")
|
||||
public void testSubclassOfMapEntry() throws Exception {
|
||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/SubclassOfMapEntry.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TwoSuperclassesConflictingProjectionKinds.kt")
|
||||
public void testTwoSuperclassesConflictingProjectionKinds() throws Exception {
|
||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesConflictingProjectionKinds.kt");
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<orderEntry type="module" module-name="frontend" scope="TEST" />
|
||||
<orderEntry type="module" module-name="frontend.java" scope="TEST" />
|
||||
<orderEntry type="module" module-name="injector-generator" scope="TEST" />
|
||||
<orderEntry type="module" module-name="cli" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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.generators;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
import org.jetbrains.jet.TestJdkKind;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaToKotlinClassMapBuilder;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
import org.jetbrains.jet.utils.Printer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.JavaToKotlinMethodMap.serializeFunction;
|
||||
import static org.jetbrains.jet.lang.resolve.java.JavaToKotlinMethodMap.serializePsiMethod;
|
||||
|
||||
public class GenerateJavaToKotlinMethodMap {
|
||||
|
||||
public static final String BUILTINS_FQNAME_PREFIX = KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.getFqName() + ".";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
JetCoreEnvironment coreEnvironment = new JetCoreEnvironment(
|
||||
CompileEnvironmentUtil.createMockDisposable(),
|
||||
CompileCompilerDependenciesTest.compilerConfigurationForTests(ConfigurationKind.JDK_ONLY, TestJdkKind.FULL_JDK));
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Printer printer = new Printer(buf);
|
||||
|
||||
printer.print(FileUtil.loadFile(new File("injector-generator/copyright.txt")))
|
||||
.println()
|
||||
.println("package org.jetbrains.jet.lang.resolve.java;")
|
||||
.println()
|
||||
.println("import com.google.common.collect.ImmutableMultimap;")
|
||||
.println()
|
||||
.println("import static org.jetbrains.jet.lang.resolve.java.JavaToKotlinMethodMap.*;")
|
||||
.println()
|
||||
.println("/* This file is generated by ", GenerateJavaToKotlinMethodMap.class.getName(), ". DO NOT EDIT! */")
|
||||
.println("@SuppressWarnings(\"unchecked\")")
|
||||
.println("class JavaToKotlinMethodMapGenerated {").pushIndent()
|
||||
.println("final ImmutableMultimap<String, JavaToKotlinMethodMap.ClassData> map;")
|
||||
.println()
|
||||
.println("JavaToKotlinMethodMapGenerated() {").pushIndent()
|
||||
.println("ImmutableMultimap.Builder<String, JavaToKotlinMethodMap.ClassData> b = ImmutableMultimap.builder();")
|
||||
.println();
|
||||
|
||||
MyMapBuilder builder = new MyMapBuilder(coreEnvironment.getProject());
|
||||
printer.printWithNoIndent(builder.toString());
|
||||
|
||||
printer.println("map = b.build();");
|
||||
printer.popIndent().println("}");
|
||||
printer.popIndent().println("}");
|
||||
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
FileWriter out =
|
||||
new FileWriter("compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinMethodMapGenerated.java");
|
||||
|
||||
out.write(buf.toString());
|
||||
out.close();
|
||||
}
|
||||
|
||||
private static class MyMapBuilder extends JavaToKotlinClassMapBuilder {
|
||||
private final Project project;
|
||||
private final StringBuilder buf = new StringBuilder();
|
||||
private final Printer printer = new Printer(buf).pushIndent().pushIndent();
|
||||
|
||||
public MyMapBuilder(@NotNull Project project) {
|
||||
this.project = project;
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void register(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor, @NotNull Direction direction) {
|
||||
processClass(javaClass, kotlinDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void register(@NotNull Class<?> javaClass,
|
||||
@NotNull ClassDescriptor kotlinDescriptor,
|
||||
@NotNull ClassDescriptor kotlinMutableDescriptor,
|
||||
@NotNull Direction direction) {
|
||||
processClass(javaClass, kotlinDescriptor);
|
||||
processClass(javaClass, kotlinMutableDescriptor);
|
||||
}
|
||||
|
||||
private void processClass(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinClass) {
|
||||
JavaFileManager javaFileManager = ServiceManager.getService(project, JavaFileManager.class);
|
||||
PsiClass psiClass = javaFileManager.findClass(javaClass.getCanonicalName(), GlobalSearchScope.allScope(project));
|
||||
assert psiClass != null;
|
||||
|
||||
List<Pair<PsiMethod, FunctionDescriptor>> methods2Functions = getClassMethods2Functions(kotlinClass, psiClass);
|
||||
if (!methods2Functions.isEmpty()) {
|
||||
appendBeforeClass(kotlinClass, psiClass);
|
||||
appendClass(methods2Functions);
|
||||
appendAfterClass();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Pair<PsiMethod, FunctionDescriptor>> getClassMethods2Functions(
|
||||
@NotNull ClassDescriptor kotlinClass,
|
||||
@NotNull PsiClass psiClass
|
||||
) {
|
||||
PsiMethod[] methods = psiClass.getMethods();
|
||||
|
||||
List<Pair<PsiMethod, FunctionDescriptor>> result = Lists.newArrayList();
|
||||
|
||||
for (DeclarationDescriptor member : kotlinClass.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||
if (!(member instanceof FunctionDescriptor) || member.getContainingDeclaration() != kotlinClass) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FunctionDescriptor fun = (FunctionDescriptor) member;
|
||||
PsiMethod foundMethod = findMethod(methods, fun);
|
||||
if (foundMethod != null) {
|
||||
result.add(Pair.create(foundMethod, fun));
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(result, new Comparator<Pair<PsiMethod, FunctionDescriptor>>() {
|
||||
@Override
|
||||
public int compare(Pair<PsiMethod, FunctionDescriptor> pair1, Pair<PsiMethod, FunctionDescriptor> pair2) {
|
||||
PsiMethod method1 = pair1.first;
|
||||
PsiMethod method2 = pair2.first;
|
||||
|
||||
String name1 = method1.getName();
|
||||
String name2 = method2.getName();
|
||||
if (!name1.equals(name2)) {
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
|
||||
String serialized1 = serializePsiMethod(method1);
|
||||
String serialized2 = serializePsiMethod(method2);
|
||||
return serialized1.compareTo(serialized2);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean match(@NotNull PsiMethod method, @NotNull FunctionDescriptor fun) {
|
||||
// Compare method an function by name and parameters count. For all methods except one (List.remove) it is enough.
|
||||
// If this changes, there will be assertion error in findMethod()
|
||||
if (method.getName().equals(fun.getName().getIdentifier())
|
||||
&& method.getParameterList().getParametersCount() == fun.getValueParameters().size()) {
|
||||
|
||||
// "special case": remove(Int) and remove(Any?) in MutableList
|
||||
if (method.getName().equals("remove") && method.getContainingClass().getName().equals("List")) {
|
||||
String psiType = method.getParameterList().getParameters()[0].getType().getPresentableText();
|
||||
String jetType = DescriptorRenderer.TEXT.renderTypeWithShortNames(fun.getValueParameters().get(0).getType());
|
||||
String string = psiType + "|" + jetType;
|
||||
|
||||
return "int|Int".equals(string) || "Object|Any?".equals(string);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod findMethod(@NotNull PsiMethod[] methods, @NotNull FunctionDescriptor fun) {
|
||||
PsiMethod found = null;
|
||||
for (PsiMethod method : methods) {
|
||||
if (match(method, fun)) {
|
||||
if (found != null) {
|
||||
throw new AssertionError("Duplicate for " + fun);
|
||||
}
|
||||
|
||||
found = method;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private void appendBeforeClass(@NotNull ClassDescriptor kotlinClass, @NotNull PsiClass psiClass) {
|
||||
String psiFqName = psiClass.getQualifiedName();
|
||||
String kotlinFqName = DescriptorUtils.getFQName(kotlinClass).toSafe().getFqName();
|
||||
|
||||
assert kotlinFqName.startsWith(BUILTINS_FQNAME_PREFIX);
|
||||
String kotlinSubQualifiedName = kotlinFqName.substring(BUILTINS_FQNAME_PREFIX.length());
|
||||
printer.println("put(b, \"", psiFqName, "\", \"", kotlinSubQualifiedName, "\",").pushIndent();
|
||||
}
|
||||
|
||||
private void appendClass(@NotNull List<Pair<PsiMethod, FunctionDescriptor>> methods2Functions) {
|
||||
int index = 0;
|
||||
for (Pair<PsiMethod, FunctionDescriptor> method2Function : methods2Functions) {
|
||||
printer.print("pair(\"", serializePsiMethod(method2Function.first), "\", \"", serializeFunction(method2Function.second),
|
||||
"\")");
|
||||
|
||||
if (index != methods2Functions.size() - 1) {
|
||||
printer.printWithNoIndent(",");
|
||||
}
|
||||
|
||||
printer.println();
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private void appendAfterClass() {
|
||||
printer.popIndent().println(");").println();
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private GenerateJavaToKotlinMethodMap() {
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
<root>
|
||||
<item name='java.util.Dictionary V put(K, V)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun put(key : K, value : V) : V?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
|
||||
<item name='java.util.AbstractList boolean add(E)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun add(e : E) : Boolean""/>
|
||||
@@ -679,12 +685,12 @@
|
||||
</item>
|
||||
<item name='java.util.AbstractMap java.util.Set<java.util.Map.Entry<K,V>> entrySet()'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun entrySet() : Set<Map.Entry<K, V>>""/>
|
||||
<val name="value" val=""fun entrySet() : MutableSet<MutableMap.MutableEntry<K, V>>""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.AbstractMap java.util.Set<K> keySet()'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun keySet() : Set<K>""/>
|
||||
<val name="value" val=""fun keySet() : MutableSet<K>""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.AbstractMap V put(K, V)'>
|
||||
@@ -699,7 +705,7 @@
|
||||
</item>
|
||||
<item name='java.util.AbstractMap java.util.Collection<V> values()'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun values() : Collection<V>""/>
|
||||
<val name="value" val=""fun values() : MutableCollection<V>""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.AbstractSequentialList void add(int, E)'>
|
||||
|
||||
Reference in New Issue
Block a user