J2K JavaToKotlinClassMap
This commit is contained in:
+1
-1
@@ -51,7 +51,7 @@ class LazyJavaAnnotationDescriptor(
|
||||
|
||||
private val type = c.storageManager.createLazyValue {
|
||||
val fqName = fqName() ?: return@createLazyValue ErrorUtils.createErrorType("No fqName: $javaAnnotation")
|
||||
val annotationClass = JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(fqName, c.module.builtIns)
|
||||
val annotationClass = JavaToKotlinClassMap.mapJavaToKotlin(fqName, c.module.builtIns)
|
||||
?: javaAnnotation.resolve()?.let { javaClass -> c.components.moduleClassResolver.resolveClass(javaClass) }
|
||||
?: createTypeForMissingDependencies(fqName)
|
||||
annotationClass.defaultType
|
||||
|
||||
+2
-2
@@ -148,7 +148,7 @@ class JavaTypeResolver(
|
||||
return c.components.reflectionTypes.kClass
|
||||
}
|
||||
|
||||
val javaToKotlin = JavaToKotlinClassMap.INSTANCE
|
||||
val javaToKotlin = JavaToKotlinClassMap
|
||||
|
||||
val howThisTypeIsUsedEffectively = when {
|
||||
attr.flexibility == FLEXIBLE_LOWER_BOUND -> MEMBER_SIGNATURE_COVARIANT
|
||||
@@ -185,7 +185,7 @@ class JavaTypeResolver(
|
||||
fun JavaType?.isSuperWildcard(): Boolean = (this as? JavaWildcardType)?.let { it.bound != null && !it.isExtends } ?: false
|
||||
|
||||
if (!typeArguments.lastOrNull().isSuperWildcard()) return false
|
||||
val mutableLastParameterVariance = JavaToKotlinClassMap.INSTANCE.convertReadOnlyToMutable(readOnlyContainer)
|
||||
val mutableLastParameterVariance = JavaToKotlinClassMap.convertReadOnlyToMutable(readOnlyContainer)
|
||||
.typeConstructor.parameters.lastOrNull()?.variance ?: return false
|
||||
|
||||
return mutableLastParameterVariance != OUT_VARIANCE
|
||||
|
||||
+1
-1
@@ -155,7 +155,7 @@ private fun ClassifierDescriptor.enhanceMutability(qualifiers: JavaTypeQualifier
|
||||
if (!position.shouldEnhance()) return this.noChange()
|
||||
if (this !is ClassDescriptor) return this.noChange() // mutability is not applicable for type parameters
|
||||
|
||||
val mapping = JavaToKotlinClassMap.INSTANCE
|
||||
val mapping = JavaToKotlinClassMap
|
||||
|
||||
when (qualifiers.mutability) {
|
||||
READ_ONLY -> {
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
|
||||
asFlexibleType().let { Pair(it.lowerBound, it.upperBound) }
|
||||
else Pair(this, this)
|
||||
|
||||
val mapping = JavaToKotlinClassMap.INSTANCE
|
||||
val mapping = JavaToKotlinClassMap
|
||||
return JavaTypeQualifiers(
|
||||
if (lower.isMarkedNullable) NULLABLE else if (!upper.isMarkedNullable) NOT_NULL else null,
|
||||
if (mapping.isReadOnly(lower)) READ_ONLY else if (mapping.isMutable(upper)) MUTABLE else null,
|
||||
|
||||
+2
-2
@@ -56,7 +56,7 @@ open class JvmBuiltInsSettings(
|
||||
deferredOwnerModuleDescriptor: () -> ModuleDescriptor,
|
||||
isAdditionalBuiltInsFeatureSupported: () -> Boolean
|
||||
) : AdditionalClassPartsProvider, PlatformDependentDeclarationFilter {
|
||||
private val j2kClassMap = JavaToKotlinClassMap.INSTANCE
|
||||
private val j2kClassMap = JavaToKotlinClassMap
|
||||
|
||||
private val ownerModuleDescriptor: ModuleDescriptor by lazy(deferredOwnerModuleDescriptor)
|
||||
private val isAdditionalBuiltInsFeatureSupported: Boolean by lazy(isAdditionalBuiltInsFeatureSupported)
|
||||
@@ -326,7 +326,7 @@ open class JvmBuiltInsSettings(
|
||||
if (isArrayOrPrimitiveArray(fqName)) {
|
||||
return true
|
||||
}
|
||||
val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName) ?: return false
|
||||
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(fqName) ?: return false
|
||||
val classViaReflection = try {
|
||||
Class.forName(javaClassId.asSingleFqName().asString())
|
||||
}
|
||||
|
||||
+2
-2
@@ -80,7 +80,7 @@ internal fun CallableDescriptor.computeJvmSignature(): String? = signatures {
|
||||
|
||||
internal val ClassDescriptor.internalName: String
|
||||
get() {
|
||||
JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqNameSafe.toUnsafe())?.let {
|
||||
JavaToKotlinClassMap.mapKotlinToJava(fqNameSafe.toUnsafe())?.let {
|
||||
return JvmClassName.byClassId(it).internalName
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ internal val ClassDescriptor.internalName: String
|
||||
|
||||
internal val ClassId.internalName: String
|
||||
get() {
|
||||
return JvmClassName.byClassId(JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(asSingleFqName().toUnsafe()) ?: this).internalName
|
||||
return JvmClassName.byClassId(JavaToKotlinClassMap.mapKotlinToJava(asSingleFqName().toUnsafe()) ?: this).internalName
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendErasedType(type: KotlinType) {
|
||||
|
||||
+1
-1
@@ -209,7 +209,7 @@ private fun <T : Any> mapBuiltInType(
|
||||
return typeFactory.createFromString("[" + JvmPrimitiveType.get(arrayElementType).desc)
|
||||
}
|
||||
|
||||
val classId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName)
|
||||
val classId = JavaToKotlinClassMap.mapKotlinToJava(fqName)
|
||||
if (classId != null) {
|
||||
return typeFactory.createObjectType(JvmClassName.byClassId(classId, typeMappingConfiguration).internalName)
|
||||
}
|
||||
|
||||
-239
@@ -1,239 +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.platform;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.name.*;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES;
|
||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getBuiltIns;
|
||||
import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getFqNameUnsafe;
|
||||
|
||||
public class JavaToKotlinClassMap implements PlatformToKotlinClassMap {
|
||||
public static final JavaToKotlinClassMap INSTANCE = new JavaToKotlinClassMap();
|
||||
|
||||
private final Map<FqNameUnsafe, ClassId> javaToKotlin = 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> readOnlyToMutable = new HashMap<FqNameUnsafe, FqName>();
|
||||
|
||||
private JavaToKotlinClassMap() {
|
||||
addTopLevel(Object.class, FQ_NAMES.any);
|
||||
addTopLevel(String.class, FQ_NAMES.string);
|
||||
addTopLevel(CharSequence.class, FQ_NAMES.charSequence);
|
||||
addTopLevel(Throwable.class, FQ_NAMES.throwable);
|
||||
addTopLevel(Cloneable.class, FQ_NAMES.cloneable);
|
||||
addTopLevel(Number.class, FQ_NAMES.number);
|
||||
addTopLevel(Comparable.class, FQ_NAMES.comparable);
|
||||
addTopLevel(Enum.class, FQ_NAMES._enum);
|
||||
addTopLevel(Annotation.class, FQ_NAMES.annotation);
|
||||
|
||||
addMutableReadOnlyPair(Iterable.class, ClassId.topLevel(FQ_NAMES.iterable), FQ_NAMES.mutableIterable);
|
||||
addMutableReadOnlyPair(Iterator.class, ClassId.topLevel(FQ_NAMES.iterator), FQ_NAMES.mutableIterator);
|
||||
addMutableReadOnlyPair(Collection.class, ClassId.topLevel(FQ_NAMES.collection), FQ_NAMES.mutableCollection);
|
||||
addMutableReadOnlyPair(List.class, ClassId.topLevel(FQ_NAMES.list), FQ_NAMES.mutableList);
|
||||
addMutableReadOnlyPair(Set.class, ClassId.topLevel(FQ_NAMES.set), FQ_NAMES.mutableSet);
|
||||
addMutableReadOnlyPair(ListIterator.class, ClassId.topLevel(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()) {
|
||||
add(
|
||||
ClassId.topLevel(jvmType.getWrapperFqName()),
|
||||
ClassId.topLevel(KotlinBuiltIns.getPrimitiveFqName(jvmType.getPrimitiveType()))
|
||||
);
|
||||
}
|
||||
|
||||
for (ClassId classId : CompanionObjectMapping.INSTANCE.allClassesWithIntrinsicCompanions()) {
|
||||
add(ClassId.topLevel(
|
||||
new FqName("kotlin.jvm.internal." + classId.getShortClassName().asString() + "CompanionObject")),
|
||||
classId.createNestedClassId(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT));
|
||||
}
|
||||
|
||||
// TODO: support also functions with >= 23 parameters
|
||||
for (int i = 0; i < 23; i++) {
|
||||
add(ClassId.topLevel(new FqName("kotlin.jvm.functions.Function" + i)), KotlinBuiltIns.getFunctionClassId(i));
|
||||
|
||||
FunctionClassDescriptor.Kind kFunction = FunctionClassDescriptor.Kind.KFunction;
|
||||
String kFun = kFunction.getPackageFqName() + "." + kFunction.getClassNamePrefix();
|
||||
addKotlinToJava(new FqName(kFun + i), ClassId.topLevel(new FqName(kFun)));
|
||||
}
|
||||
|
||||
addKotlinToJava(FQ_NAMES.nothing.toSafe(), classId(Void.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* E.g.
|
||||
* java.lang.String -> kotlin.String
|
||||
* java.lang.Integer -> kotlin.Int
|
||||
* kotlin.jvm.internal.IntCompanionObject -> kotlin.Int.Companion
|
||||
* java.util.List -> kotlin.List
|
||||
* java.util.Map.Entry -> kotlin.Map.Entry
|
||||
* java.lang.Void -> null
|
||||
* kotlin.jvm.functions.Function3 -> kotlin.Function3
|
||||
*/
|
||||
@Nullable
|
||||
public ClassId mapJavaToKotlin(@NotNull FqName fqName) {
|
||||
return javaToKotlin.get(fqName.toUnsafe());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ClassDescriptor mapJavaToKotlin(@NotNull FqName fqName, @NotNull KotlinBuiltIns builtIns) {
|
||||
ClassId kotlinClassId = mapJavaToKotlin(fqName);
|
||||
return kotlinClassId != null ? builtIns.getBuiltInClassByFqName(kotlinClassId.asSingleFqName()) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* E.g.
|
||||
* kotlin.Throwable -> java.lang.Throwable
|
||||
* kotlin.Int -> java.lang.Integer
|
||||
* kotlin.Int.Companion -> kotlin.jvm.internal.IntCompanionObject
|
||||
* kotlin.Nothing -> java.lang.Void
|
||||
* kotlin.IntArray -> null
|
||||
* kotlin.Function3 -> kotlin.jvm.functions.Function3
|
||||
* kotlin.reflect.KFunction3 -> kotlin.reflect.KFunction
|
||||
*/
|
||||
@Nullable
|
||||
public ClassId mapKotlinToJava(@NotNull FqNameUnsafe kotlinFqName) {
|
||||
return kotlinToJava.get(kotlinFqName);
|
||||
}
|
||||
|
||||
private void addMutableReadOnlyPair(
|
||||
@NotNull Class<?> javaClass,
|
||||
@NotNull ClassId kotlinReadOnlyClassId,
|
||||
@NotNull FqName kotlinMutableFqName
|
||||
) {
|
||||
ClassId javaClassId = classId(javaClass);
|
||||
|
||||
add(javaClassId, kotlinReadOnlyClassId);
|
||||
addKotlinToJava(kotlinMutableFqName, javaClassId);
|
||||
|
||||
FqName kotlinReadOnlyFqName = kotlinReadOnlyClassId.asSingleFqName();
|
||||
mutableToReadOnly.put(kotlinMutableFqName.toUnsafe(), kotlinReadOnlyFqName);
|
||||
readOnlyToMutable.put(kotlinReadOnlyFqName.toUnsafe(), kotlinMutableFqName);
|
||||
}
|
||||
|
||||
private void add(@NotNull ClassId javaClassId, @NotNull ClassId kotlinClassId) {
|
||||
addJavaToKotlin(javaClassId, kotlinClassId);
|
||||
addKotlinToJava(kotlinClassId.asSingleFqName(), javaClassId);
|
||||
}
|
||||
|
||||
private void addTopLevel(@NotNull Class<?> javaClass, @NotNull FqNameUnsafe kotlinFqName) {
|
||||
addTopLevel(javaClass, kotlinFqName.toSafe());
|
||||
}
|
||||
|
||||
private void addTopLevel(@NotNull Class<?> javaClass, @NotNull FqName kotlinFqName) {
|
||||
add(classId(javaClass), ClassId.topLevel(kotlinFqName));
|
||||
}
|
||||
|
||||
private void addJavaToKotlin(@NotNull ClassId javaClassId, @NotNull ClassId kotlinClassId) {
|
||||
javaToKotlin.put(javaClassId.asSingleFqName().toUnsafe(), kotlinClassId);
|
||||
}
|
||||
|
||||
private void addKotlinToJava(@NotNull FqName kotlinFqNameUnsafe, @NotNull ClassId javaClassId) {
|
||||
kotlinToJava.put(kotlinFqNameUnsafe.toUnsafe(), javaClassId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClassId classId(@NotNull Class<?> clazz) {
|
||||
assert !clazz.isPrimitive() && !clazz.isArray() : "Invalid class: " + clazz;
|
||||
Class<?> outer = clazz.getDeclaringClass();
|
||||
return outer == null
|
||||
? ClassId.topLevel(new FqName(clazz.getCanonicalName()))
|
||||
: classId(outer).createNestedClassId(Name.identifier(clazz.getSimpleName()));
|
||||
}
|
||||
|
||||
public boolean isJavaPlatformClass(@NotNull FqName fqName) {
|
||||
return mapJavaToKotlin(fqName) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ClassDescriptor> mapPlatformClass(@NotNull FqName fqName, @NotNull KotlinBuiltIns builtIns) {
|
||||
ClassDescriptor kotlinAnalog = mapJavaToKotlin(fqName, builtIns);
|
||||
if (kotlinAnalog == null) return Collections.emptySet();
|
||||
|
||||
FqName kotlinMutableAnalogFqName = readOnlyToMutable.get(getFqNameUnsafe(kotlinAnalog));
|
||||
if (kotlinMutableAnalogFqName == null) return Collections.singleton(kotlinAnalog);
|
||||
|
||||
return Arrays.asList(kotlinAnalog, builtIns.getBuiltInClassByFqName(kotlinMutableAnalogFqName));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<ClassDescriptor> mapPlatformClass(@NotNull ClassDescriptor classDescriptor) {
|
||||
FqNameUnsafe className = DescriptorUtils.getFqName(classDescriptor);
|
||||
return className.isSafe()
|
||||
? mapPlatformClass(className.toSafe(), getBuiltIns(classDescriptor))
|
||||
: Collections.<ClassDescriptor>emptySet();
|
||||
}
|
||||
|
||||
public boolean isMutable(@NotNull ClassDescriptor mutable) {
|
||||
return mutableToReadOnly.containsKey(DescriptorUtils.getFqName(mutable));
|
||||
}
|
||||
|
||||
public boolean isMutable(@NotNull KotlinType type) {
|
||||
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(type);
|
||||
return classDescriptor != null && isMutable(classDescriptor);
|
||||
}
|
||||
|
||||
public boolean isReadOnly(@NotNull ClassDescriptor readOnly) {
|
||||
return readOnlyToMutable.containsKey(DescriptorUtils.getFqName(readOnly));
|
||||
}
|
||||
|
||||
public boolean isReadOnly(@NotNull KotlinType type) {
|
||||
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(type);
|
||||
return classDescriptor != null && isReadOnly(classDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor convertMutableToReadOnly(@NotNull ClassDescriptor mutable) {
|
||||
return convertToOppositeMutability(mutable, mutableToReadOnly, "mutable");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ClassDescriptor convertToOppositeMutability(
|
||||
@NotNull ClassDescriptor descriptor,
|
||||
@NotNull Map<FqNameUnsafe, FqName> map,
|
||||
@NotNull String mutabilityKindName
|
||||
) {
|
||||
FqName oppositeClassFqName = map.get(DescriptorUtils.getFqName(descriptor));
|
||||
if (oppositeClassFqName == null) {
|
||||
throw new IllegalArgumentException("Given class " + descriptor + " is not a " + mutabilityKindName + " collection");
|
||||
}
|
||||
return getBuiltIns(descriptor).getBuiltInClassByFqName(oppositeClassFqName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor convertReadOnlyToMutable(@NotNull ClassDescriptor readOnly) {
|
||||
return convertToOppositeMutability(readOnly, readOnlyToMutable, "read-only");
|
||||
}
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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.platform
|
||||
|
||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.util.*
|
||||
|
||||
object JavaToKotlinClassMap : PlatformToKotlinClassMap {
|
||||
|
||||
private val javaToKotlin = HashMap<FqNameUnsafe, ClassId>()
|
||||
private val kotlinToJava = HashMap<FqNameUnsafe, ClassId>()
|
||||
|
||||
private val mutableToReadOnly = HashMap<FqNameUnsafe, FqName>()
|
||||
private val readOnlyToMutable = HashMap<FqNameUnsafe, FqName>()
|
||||
|
||||
init {
|
||||
addTopLevel(Any::class.java, FQ_NAMES.any)
|
||||
addTopLevel(String::class.java, FQ_NAMES.string)
|
||||
addTopLevel(CharSequence::class.java, FQ_NAMES.charSequence)
|
||||
addTopLevel(Throwable::class.java, FQ_NAMES.throwable)
|
||||
addTopLevel(Cloneable::class.java, FQ_NAMES.cloneable)
|
||||
addTopLevel(Number::class.java, FQ_NAMES.number)
|
||||
addTopLevel(Comparable::class.java, FQ_NAMES.comparable)
|
||||
addTopLevel(Enum::class.java, FQ_NAMES._enum)
|
||||
addTopLevel(Annotation::class.java, FQ_NAMES.annotation)
|
||||
|
||||
addMutableReadOnlyPair(Iterable::class.java, ClassId.topLevel(FQ_NAMES.iterable), FQ_NAMES.mutableIterable)
|
||||
addMutableReadOnlyPair(Iterator::class.java, ClassId.topLevel(FQ_NAMES.iterator), FQ_NAMES.mutableIterator)
|
||||
addMutableReadOnlyPair(Collection::class.java, ClassId.topLevel(FQ_NAMES.collection), FQ_NAMES.mutableCollection)
|
||||
addMutableReadOnlyPair(List::class.java, ClassId.topLevel(FQ_NAMES.list), FQ_NAMES.mutableList)
|
||||
addMutableReadOnlyPair(Set::class.java, ClassId.topLevel(FQ_NAMES.set), FQ_NAMES.mutableSet)
|
||||
addMutableReadOnlyPair(ListIterator::class.java, ClassId.topLevel(FQ_NAMES.listIterator), FQ_NAMES.mutableListIterator)
|
||||
|
||||
val mapClassId = ClassId.topLevel(FQ_NAMES.map)
|
||||
addMutableReadOnlyPair(Map::class.java, mapClassId, FQ_NAMES.mutableMap)
|
||||
addMutableReadOnlyPair(Map.Entry::class.java, mapClassId.createNestedClassId(FQ_NAMES.mapEntry.shortName()), FQ_NAMES.mutableMapEntry)
|
||||
|
||||
for (jvmType in JvmPrimitiveType.values()) {
|
||||
add(ClassId.topLevel(jvmType.wrapperFqName),
|
||||
ClassId.topLevel(KotlinBuiltIns.getPrimitiveFqName(jvmType.primitiveType)))
|
||||
}
|
||||
|
||||
for (classId in CompanionObjectMapping.allClassesWithIntrinsicCompanions()) {
|
||||
add(ClassId.topLevel(FqName("kotlin.jvm.internal." + classId.shortClassName.asString() + "CompanionObject")),
|
||||
classId.createNestedClassId(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT))
|
||||
}
|
||||
|
||||
// TODO: support also functions with >= 23 parameters
|
||||
for (i in 0..22) {
|
||||
add(ClassId.topLevel(FqName("kotlin.jvm.functions.Function" + i)), KotlinBuiltIns.getFunctionClassId(i))
|
||||
|
||||
val kFunction = FunctionClassDescriptor.Kind.KFunction
|
||||
val kFun = kFunction.packageFqName.toString() + "." + kFunction.classNamePrefix
|
||||
addKotlinToJava(FqName(kFun + i), ClassId.topLevel(FqName(kFun)))
|
||||
}
|
||||
|
||||
addKotlinToJava(FQ_NAMES.nothing.toSafe(), classId(Void::class.java))
|
||||
}
|
||||
|
||||
/**
|
||||
* E.g.
|
||||
* java.lang.String -> kotlin.String
|
||||
* java.lang.Integer -> kotlin.Int
|
||||
* kotlin.jvm.internal.IntCompanionObject -> kotlin.Int.Companion
|
||||
* java.util.List -> kotlin.List
|
||||
* java.util.Map.Entry -> kotlin.Map.Entry
|
||||
* java.lang.Void -> null
|
||||
* kotlin.jvm.functions.Function3 -> kotlin.Function3
|
||||
*/
|
||||
fun mapJavaToKotlin(fqName: FqName): ClassId? {
|
||||
return javaToKotlin[fqName.toUnsafe()]
|
||||
}
|
||||
|
||||
fun mapJavaToKotlin(fqName: FqName, builtIns: KotlinBuiltIns): ClassDescriptor? {
|
||||
val kotlinClassId = mapJavaToKotlin(fqName)
|
||||
return if (kotlinClassId != null) builtIns.getBuiltInClassByFqName(kotlinClassId.asSingleFqName()) else null
|
||||
}
|
||||
|
||||
/**
|
||||
* E.g.
|
||||
* kotlin.Throwable -> java.lang.Throwable
|
||||
* kotlin.Int -> java.lang.Integer
|
||||
* kotlin.Int.Companion -> kotlin.jvm.internal.IntCompanionObject
|
||||
* kotlin.Nothing -> java.lang.Void
|
||||
* kotlin.IntArray -> null
|
||||
* kotlin.Function3 -> kotlin.jvm.functions.Function3
|
||||
* kotlin.reflect.KFunction3 -> kotlin.reflect.KFunction
|
||||
*/
|
||||
fun mapKotlinToJava(kotlinFqName: FqNameUnsafe): ClassId? {
|
||||
return kotlinToJava[kotlinFqName]
|
||||
}
|
||||
|
||||
private fun addMutableReadOnlyPair(
|
||||
javaClass: Class<*>,
|
||||
kotlinReadOnlyClassId: ClassId,
|
||||
kotlinMutableFqName: FqName
|
||||
) {
|
||||
val javaClassId = classId(javaClass)
|
||||
|
||||
add(javaClassId, kotlinReadOnlyClassId)
|
||||
addKotlinToJava(kotlinMutableFqName, javaClassId)
|
||||
|
||||
val kotlinReadOnlyFqName = kotlinReadOnlyClassId.asSingleFqName()
|
||||
mutableToReadOnly.put(kotlinMutableFqName.toUnsafe(), kotlinReadOnlyFqName)
|
||||
readOnlyToMutable.put(kotlinReadOnlyFqName.toUnsafe(), kotlinMutableFqName)
|
||||
}
|
||||
|
||||
private fun add(javaClassId: ClassId, kotlinClassId: ClassId) {
|
||||
addJavaToKotlin(javaClassId, kotlinClassId)
|
||||
addKotlinToJava(kotlinClassId.asSingleFqName(), javaClassId)
|
||||
}
|
||||
|
||||
private fun addTopLevel(javaClass: Class<*>, kotlinFqName: FqNameUnsafe) {
|
||||
addTopLevel(javaClass, kotlinFqName.toSafe())
|
||||
}
|
||||
|
||||
private fun addTopLevel(javaClass: Class<*>, kotlinFqName: FqName) {
|
||||
add(classId(javaClass), ClassId.topLevel(kotlinFqName))
|
||||
}
|
||||
|
||||
private fun addJavaToKotlin(javaClassId: ClassId, kotlinClassId: ClassId) {
|
||||
javaToKotlin.put(javaClassId.asSingleFqName().toUnsafe(), kotlinClassId)
|
||||
}
|
||||
|
||||
private fun addKotlinToJava(kotlinFqNameUnsafe: FqName, javaClassId: ClassId) {
|
||||
kotlinToJava.put(kotlinFqNameUnsafe.toUnsafe(), javaClassId)
|
||||
}
|
||||
|
||||
fun isJavaPlatformClass(fqName: FqName): Boolean = mapJavaToKotlin(fqName) != null
|
||||
|
||||
fun mapPlatformClass(fqName: FqName, builtIns: KotlinBuiltIns): Collection<ClassDescriptor> {
|
||||
val kotlinAnalog = mapJavaToKotlin(fqName, builtIns) ?: return emptySet()
|
||||
|
||||
val kotlinMutableAnalogFqName = readOnlyToMutable[kotlinAnalog.fqNameUnsafe] ?: return setOf(kotlinAnalog)
|
||||
|
||||
return Arrays.asList(kotlinAnalog, builtIns.getBuiltInClassByFqName(kotlinMutableAnalogFqName))
|
||||
}
|
||||
|
||||
override fun mapPlatformClass(classDescriptor: ClassDescriptor): Collection<ClassDescriptor> {
|
||||
val className = DescriptorUtils.getFqName(classDescriptor)
|
||||
return if (className.isSafe)
|
||||
mapPlatformClass(className.toSafe(), classDescriptor.builtIns)
|
||||
else
|
||||
emptySet<ClassDescriptor>()
|
||||
}
|
||||
|
||||
fun isMutable(mutable: ClassDescriptor): Boolean = mutableToReadOnly.containsKey(DescriptorUtils.getFqName(mutable))
|
||||
|
||||
fun isMutable(type: KotlinType): Boolean {
|
||||
val classDescriptor = TypeUtils.getClassDescriptor(type)
|
||||
return classDescriptor != null && isMutable(classDescriptor)
|
||||
}
|
||||
|
||||
fun isReadOnly(readOnly: ClassDescriptor): Boolean = readOnlyToMutable.containsKey(DescriptorUtils.getFqName(readOnly))
|
||||
|
||||
fun isReadOnly(type: KotlinType): Boolean {
|
||||
val classDescriptor = TypeUtils.getClassDescriptor(type)
|
||||
return classDescriptor != null && isReadOnly(classDescriptor)
|
||||
}
|
||||
|
||||
fun convertMutableToReadOnly(mutable: ClassDescriptor): ClassDescriptor {
|
||||
return convertToOppositeMutability(mutable, mutableToReadOnly, "mutable")
|
||||
}
|
||||
|
||||
fun convertReadOnlyToMutable(readOnly: ClassDescriptor): ClassDescriptor {
|
||||
return convertToOppositeMutability(readOnly, readOnlyToMutable, "read-only")
|
||||
}
|
||||
|
||||
private fun classId(clazz: Class<*>): ClassId {
|
||||
assert(!clazz.isPrimitive && !clazz.isArray) { "Invalid class: " + clazz }
|
||||
val outer = clazz.declaringClass
|
||||
return if (outer == null)
|
||||
ClassId.topLevel(FqName(clazz.canonicalName))
|
||||
else
|
||||
classId(outer).createNestedClassId(Name.identifier(clazz.simpleName))
|
||||
}
|
||||
|
||||
private fun convertToOppositeMutability(
|
||||
descriptor: ClassDescriptor,
|
||||
map: Map<FqNameUnsafe, FqName>,
|
||||
mutabilityKindName: String
|
||||
): ClassDescriptor {
|
||||
val oppositeClassFqName = map[DescriptorUtils.getFqName(descriptor)] ?: throw IllegalArgumentException("Given class $descriptor is not a $mutabilityKindName collection")
|
||||
return descriptor.builtIns.getBuiltInClassByFqName(oppositeClassFqName)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -42,7 +42,7 @@ object ClassMapperLite {
|
||||
if (simpleName == KotlinBuiltIns.FQ_NAMES.unit.shortName().asString()) return "V"
|
||||
}
|
||||
|
||||
val javaClassId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(classId.asSingleFqName().toUnsafe())
|
||||
val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(classId.asSingleFqName().toUnsafe())
|
||||
if (javaClassId != null) {
|
||||
return "L" + javaClassId.asString().replace('.', '$') + ";"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user