Use ClassId instead of FqName in JavaToKotlinClassMap

Extract mapJavaToKotlin which returns ClassId and needs no KotlinBuiltIns
instance
This commit is contained in:
Alexander Udalov
2016-10-13 19:54:27 +03:00
parent 0e9f29fdba
commit 2f81d48f5e
5 changed files with 63 additions and 65 deletions
@@ -56,7 +56,6 @@ import org.jetbrains.kotlin.psi.debugText.getDebugText
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import java.util.* import java.util.*
import javax.swing.Icon import javax.swing.Icon
@@ -411,11 +410,10 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
if (qualifiedName == DescriptorUtils.getFqName(classDescriptor).asString()) return true if (qualifiedName == DescriptorUtils.getFqName(classDescriptor).asString()) return true
val fqName = FqNameUnsafe(qualifiedName) val fqName = FqNameUnsafe(qualifiedName)
val mappedDescriptor = val mappedQName =
if (fqName.isSafe) if (fqName.isSafe)
JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(fqName.toSafe(), classDescriptor.builtIns) JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(fqName.toSafe())?.asSingleFqName()?.asString()
else null else null
val mappedQName = if (mappedDescriptor == null) null else DescriptorUtils.getFqName(mappedDescriptor).asString()
if (qualifiedName == mappedQName) return true if (qualifiedName == mappedQName) return true
for (superType in classDescriptor.typeConstructor.supertypes) { for (superType in classDescriptor.typeConstructor.supertypes) {
@@ -38,45 +38,50 @@ import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getF
public class JavaToKotlinClassMap implements PlatformToKotlinClassMap { public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
public static final JavaToKotlinClassMap INSTANCE = new JavaToKotlinClassMap(); public static final JavaToKotlinClassMap INSTANCE = new JavaToKotlinClassMap();
private final Map<FqNameUnsafe, FqName> javaToKotlin = new HashMap<FqNameUnsafe, FqName>(); private final Map<FqNameUnsafe, ClassId> javaToKotlin = new HashMap<FqNameUnsafe, ClassId>();
private final Map<FqNameUnsafe, ClassId> kotlinToJava = new HashMap<FqNameUnsafe, ClassId>(); private final Map<FqNameUnsafe, ClassId> kotlinToJava = new HashMap<FqNameUnsafe, ClassId>();
private final Map<FqNameUnsafe, FqName> mutableToReadOnly = new HashMap<FqNameUnsafe, FqName>(); private final Map<FqNameUnsafe, FqName> mutableToReadOnly = new HashMap<FqNameUnsafe, FqName>();
private final Map<FqNameUnsafe, FqName> readOnlyToMutable = new HashMap<FqNameUnsafe, FqName>(); private final Map<FqNameUnsafe, FqName> readOnlyToMutable = new HashMap<FqNameUnsafe, FqName>();
private JavaToKotlinClassMap() { private JavaToKotlinClassMap() {
add(Object.class, FQ_NAMES.any); addTopLevel(Object.class, FQ_NAMES.any);
add(String.class, FQ_NAMES.string); addTopLevel(String.class, FQ_NAMES.string);
add(CharSequence.class, FQ_NAMES.charSequence); addTopLevel(CharSequence.class, FQ_NAMES.charSequence);
add(Throwable.class, FQ_NAMES.throwable); addTopLevel(Throwable.class, FQ_NAMES.throwable);
add(Cloneable.class, FQ_NAMES.cloneable); addTopLevel(Cloneable.class, FQ_NAMES.cloneable);
add(Number.class, FQ_NAMES.number); addTopLevel(Number.class, FQ_NAMES.number);
add(Comparable.class, FQ_NAMES.comparable); addTopLevel(Comparable.class, FQ_NAMES.comparable);
add(Enum.class, FQ_NAMES._enum); addTopLevel(Enum.class, FQ_NAMES._enum);
add(Annotation.class, FQ_NAMES.annotation); addTopLevel(Annotation.class, FQ_NAMES.annotation);
add(Iterable.class, FQ_NAMES.iterable, FQ_NAMES.mutableIterable); addMutableReadOnlyPair(Iterable.class, ClassId.topLevel(FQ_NAMES.iterable), FQ_NAMES.mutableIterable);
add(Iterator.class, FQ_NAMES.iterator, FQ_NAMES.mutableIterator); addMutableReadOnlyPair(Iterator.class, ClassId.topLevel(FQ_NAMES.iterator), FQ_NAMES.mutableIterator);
add(Collection.class, FQ_NAMES.collection, FQ_NAMES.mutableCollection); addMutableReadOnlyPair(Collection.class, ClassId.topLevel(FQ_NAMES.collection), FQ_NAMES.mutableCollection);
add(List.class, FQ_NAMES.list, FQ_NAMES.mutableList); addMutableReadOnlyPair(List.class, ClassId.topLevel(FQ_NAMES.list), FQ_NAMES.mutableList);
add(Set.class, FQ_NAMES.set, FQ_NAMES.mutableSet); addMutableReadOnlyPair(Set.class, ClassId.topLevel(FQ_NAMES.set), FQ_NAMES.mutableSet);
add(Map.class, FQ_NAMES.map, FQ_NAMES.mutableMap); addMutableReadOnlyPair(ListIterator.class, ClassId.topLevel(FQ_NAMES.listIterator), FQ_NAMES.mutableListIterator);
add(Map.Entry.class, FQ_NAMES.mapEntry, FQ_NAMES.mutableMapEntry);
add(ListIterator.class, FQ_NAMES.listIterator, FQ_NAMES.mutableListIterator); ClassId mapClassId = ClassId.topLevel(FQ_NAMES.map);
addMutableReadOnlyPair(Map.class, mapClassId, FQ_NAMES.mutableMap);
addMutableReadOnlyPair(Map.Entry.class, mapClassId.createNestedClassId(FQ_NAMES.mapEntry.shortName()), FQ_NAMES.mutableMapEntry);
for (JvmPrimitiveType jvmType : JvmPrimitiveType.values()) { for (JvmPrimitiveType jvmType : JvmPrimitiveType.values()) {
add(ClassId.topLevel(jvmType.getWrapperFqName()), KotlinBuiltIns.getPrimitiveFqName(jvmType.getPrimitiveType())); add(
ClassId.topLevel(jvmType.getWrapperFqName()),
ClassId.topLevel(KotlinBuiltIns.getPrimitiveFqName(jvmType.getPrimitiveType()))
);
} }
for (FqName fqName : CompanionObjectMapping.INSTANCE.allClassesWithIntrinsicCompanions()) { for (ClassId classId : CompanionObjectMapping.INSTANCE.allClassesWithIntrinsicCompanions()) {
add(ClassId.topLevel( add(ClassId.topLevel(
new FqName("kotlin.jvm.internal." + fqName.shortName().asString() + "CompanionObject")), new FqName("kotlin.jvm.internal." + classId.getShortClassName().asString() + "CompanionObject")),
fqName.child(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT)); classId.createNestedClassId(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT));
} }
// TODO: support also functions with >= 23 parameters // TODO: support also functions with >= 23 parameters
for (int i = 0; i < 23; i++) { for (int i = 0; i < 23; i++) {
add(ClassId.topLevel(new FqName("kotlin.jvm.functions.Function" + i)), KotlinBuiltIns.getFunctionFqName(i)); add(ClassId.topLevel(new FqName("kotlin.jvm.functions.Function" + i)), KotlinBuiltIns.getFunctionClassId(i));
FunctionClassDescriptor.Kind kFunction = FunctionClassDescriptor.Kind.KFunction; FunctionClassDescriptor.Kind kFunction = FunctionClassDescriptor.Kind.KFunction;
String kFun = kFunction.getPackageFqName() + "." + kFunction.getClassNamePrefix(); String kFun = kFunction.getPackageFqName() + "." + kFunction.getClassNamePrefix();
@@ -96,10 +101,15 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
* java.lang.Void -> null * java.lang.Void -> null
* kotlin.jvm.functions.Function3 -> kotlin.Function3 * kotlin.jvm.functions.Function3 -> kotlin.Function3
*/ */
@Nullable
public ClassId mapJavaToKotlin(@NotNull FqName fqName) {
return javaToKotlin.get(fqName.toUnsafe());
}
@Nullable @Nullable
public ClassDescriptor mapJavaToKotlin(@NotNull FqName fqName, @NotNull KotlinBuiltIns builtIns) { public ClassDescriptor mapJavaToKotlin(@NotNull FqName fqName, @NotNull KotlinBuiltIns builtIns) {
FqName kotlinFqName = javaToKotlin.get(fqName.toUnsafe()); ClassId kotlinClassId = mapJavaToKotlin(fqName);
return kotlinFqName != null ? builtIns.getBuiltInClassByFqName(kotlinFqName) : null; return kotlinClassId != null ? builtIns.getBuiltInClassByFqName(kotlinClassId.asSingleFqName()) : null;
} }
/** /**
@@ -117,35 +127,36 @@ public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
return kotlinToJava.get(kotlinFqName); return kotlinToJava.get(kotlinFqName);
} }
private void add( private void addMutableReadOnlyPair(
@NotNull Class<?> javaClass, @NotNull Class<?> javaClass,
@NotNull FqName kotlinReadOnlyFqName, @NotNull ClassId kotlinReadOnlyClassId,
@NotNull FqName kotlinMutableFqName @NotNull FqName kotlinMutableFqName
) { ) {
ClassId javaClassId = classId(javaClass); ClassId javaClassId = classId(javaClass);
add(javaClassId, kotlinReadOnlyFqName); add(javaClassId, kotlinReadOnlyClassId);
addKotlinToJava(kotlinMutableFqName, javaClassId); addKotlinToJava(kotlinMutableFqName, javaClassId);
FqName kotlinReadOnlyFqName = kotlinReadOnlyClassId.asSingleFqName();
mutableToReadOnly.put(kotlinMutableFqName.toUnsafe(), kotlinReadOnlyFqName); mutableToReadOnly.put(kotlinMutableFqName.toUnsafe(), kotlinReadOnlyFqName);
readOnlyToMutable.put(kotlinReadOnlyFqName.toUnsafe(), kotlinMutableFqName); readOnlyToMutable.put(kotlinReadOnlyFqName.toUnsafe(), kotlinMutableFqName);
} }
private void add(@NotNull ClassId javaClassId, @NotNull FqName kotlinFqName) { private void add(@NotNull ClassId javaClassId, @NotNull ClassId kotlinClassId) {
addJavaToKotlin(javaClassId, kotlinFqName); addJavaToKotlin(javaClassId, kotlinClassId);
addKotlinToJava(kotlinFqName, javaClassId); addKotlinToJava(kotlinClassId.asSingleFqName(), javaClassId);
} }
private void add(@NotNull Class<?> javaClass, @NotNull FqNameUnsafe kotlinFqName) { private void addTopLevel(@NotNull Class<?> javaClass, @NotNull FqNameUnsafe kotlinFqName) {
add(javaClass, kotlinFqName.toSafe()); addTopLevel(javaClass, kotlinFqName.toSafe());
} }
private void add(@NotNull Class<?> javaClass, @NotNull FqName kotlinFqName) { private void addTopLevel(@NotNull Class<?> javaClass, @NotNull FqName kotlinFqName) {
add(classId(javaClass), kotlinFqName); add(classId(javaClass), ClassId.topLevel(kotlinFqName));
} }
private void addJavaToKotlin(@NotNull ClassId javaClassId, @NotNull FqName kotlinFqName) { private void addJavaToKotlin(@NotNull ClassId javaClassId, @NotNull ClassId kotlinClassId) {
javaToKotlin.put(javaClassId.asSingleFqName().toUnsafe(), kotlinFqName); javaToKotlin.put(javaClassId.asSingleFqName().toUnsafe(), kotlinClassId);
} }
private void addKotlinToJava(@NotNull FqName kotlinFqNameUnsafe, @NotNull ClassId javaClassId) { private void addKotlinToJava(@NotNull FqName kotlinFqNameUnsafe, @NotNull ClassId javaClassId) {
@@ -17,29 +17,20 @@
package org.jetbrains.kotlin.builtins package org.jetbrains.kotlin.builtins
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import java.util.* import java.util.*
object CompanionObjectMapping { object CompanionObjectMapping {
private val classesFqNames = linkedSetOf<FqName>() private val classIds =
(PrimitiveType.NUMBER_TYPES.map(KotlinBuiltIns::getPrimitiveFqName) +
KotlinBuiltIns.FQ_NAMES.string.toSafe() +
KotlinBuiltIns.FQ_NAMES._enum.toSafe()).mapTo(linkedSetOf<ClassId>(), ClassId::topLevel)
init { fun allClassesWithIntrinsicCompanions(): Set<ClassId> =
for (type in PrimitiveType.NUMBER_TYPES) { Collections.unmodifiableSet(classIds)
classesFqNames.add(KotlinBuiltIns.getPrimitiveFqName(type))
}
classesFqNames.add(KotlinBuiltIns.FQ_NAMES.string.toSafe())
classesFqNames.add(KotlinBuiltIns.FQ_NAMES._enum.toSafe())
}
fun allClassesWithIntrinsicCompanions(): Set<FqName> = fun isMappedIntrinsicCompanionObject(classDescriptor: ClassDescriptor): Boolean =
Collections.unmodifiableSet(classesFqNames) DescriptorUtils.isCompanionObject(classDescriptor) && classDescriptor.classId?.outerClassId in classIds
fun isMappedIntrinsicCompanionObject(classDescriptor: ClassDescriptor): Boolean {
if (!DescriptorUtils.isCompanionObject(classDescriptor)) return false
val fqName = DescriptorUtils.getFqName(classDescriptor.containingDeclaration)
if (!fqName.isSafe) return false
return fqName.toSafe() in classesFqNames
}
} }
@@ -429,8 +429,8 @@ public abstract class KotlinBuiltIns {
} }
@NotNull @NotNull
public static FqName getFunctionFqName(int parameterCount) { public static ClassId getFunctionClassId(int parameterCount) {
return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(getFunctionName(parameterCount))); return new ClassId(BUILT_INS_PACKAGE_FQ_NAME, Name.identifier(getFunctionName(parameterCount)));
} }
@NotNull @NotNull
@@ -16,7 +16,6 @@
package kotlin.reflect.jvm.internal package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -33,7 +32,6 @@ import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver import org.jetbrains.kotlin.serialization.deserialization.NameResolver
@@ -271,7 +269,7 @@ internal object RuntimeTypeMapper {
val classId = klass.classId val classId = klass.classId
if (!classId.isLocal) { if (!classId.isLocal) {
JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(classId.asSingleFqName(), DefaultBuiltIns.Instance)?.let { return it.classId!! } JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(classId.asSingleFqName())?.let { return it }
} }
return classId return classId