diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index ed6db12e6fd..5776f9c1281 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAnnotationNames; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader; +import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext; @@ -75,6 +76,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method; import java.util.*; +import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES; import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass; @@ -278,25 +280,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - private static final Map KOTLIN_MARKER_INTERFACES = new HashMap(); + private static final Map KOTLIN_MARKER_INTERFACES = new HashMap(); static { - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.Iterator", "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.Iterable", "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.Collection", "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.List", "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.ListIterator", "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.Set", "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.Map", "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.Map.Entry", "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.iterator, "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.iterable, "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.collection, "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.list, "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.listIterator, "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.set, "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.map, "kotlin/jvm/internal/markers/KMappedMarker"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mapEntry, "kotlin/jvm/internal/markers/KMappedMarker"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableIterator", "kotlin/jvm/internal/markers/KMutableIterator"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableIterable", "kotlin/jvm/internal/markers/KMutableIterable"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableCollection", "kotlin/jvm/internal/markers/KMutableCollection"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableList", "kotlin/jvm/internal/markers/KMutableList"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableListIterator", "kotlin/jvm/internal/markers/KMutableListIterator"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableSet", "kotlin/jvm/internal/markers/KMutableSet"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableMap", "kotlin/jvm/internal/markers/KMutableMap"); - KOTLIN_MARKER_INTERFACES.put("kotlin.collections.MutableMap.MutableEntry", "kotlin/jvm/internal/markers/KMutableMap$Entry"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableIterator, "kotlin/jvm/internal/markers/KMutableIterator"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableIterable, "kotlin/jvm/internal/markers/KMutableIterable"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableCollection, "kotlin/jvm/internal/markers/KMutableCollection"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableList, "kotlin/jvm/internal/markers/KMutableList"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableListIterator, "kotlin/jvm/internal/markers/KMutableListIterator"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableSet, "kotlin/jvm/internal/markers/KMutableSet"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableMap, "kotlin/jvm/internal/markers/KMutableMap"); + KOTLIN_MARKER_INTERFACES.put(FQ_NAMES.mutableMapEntry, "kotlin/jvm/internal/markers/KMutableMap$Entry"); } @NotNull @@ -326,7 +328,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { String jvmInterfaceInternalName = jvmInterfaceType.getInternalName(); superInterfaces.add(jvmInterfaceInternalName); - String kotlinInterfaceName = DescriptorUtils.getFqName(supertype.getConstructor().getDeclarationDescriptor()).asString(); + FqName kotlinInterfaceName = DescriptorUtils.getFqName(supertype.getConstructor().getDeclarationDescriptor()).toSafe(); String kotlinMarkerInterfaceInternalName = KOTLIN_MARKER_INTERFACES.get(kotlinInterfaceName); if (kotlinMarkerInterfaceInternalName != null) { kotlinMarkerInterfaces.add(kotlinMarkerInterfaceInternalName); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/TypeIntrinsics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/TypeIntrinsics.kt index 8b296f6e51e..c7e4cbf7b86 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/TypeIntrinsics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/TypeIntrinsics.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.codegen.intrinsics +import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils @@ -114,23 +116,35 @@ object TypeIntrinsics { private val IS_FUNCTON_OF_ARITY_DESCRIPTOR = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getObjectType("java/lang/Object"), Type.INT_TYPE) - private val IS_MUTABLE_COLLECTION_METHOD_NAME = hashMapOf( - "kotlin.collections.MutableIterator" to "isMutableIterator", - "kotlin.collections.MutableIterable" to "isMutableIterable", - "kotlin.collections.MutableCollection" to "isMutableCollection", - "kotlin.collections.MutableList" to "isMutableList", - "kotlin.collections.MutableListIterator" to "isMutableListIterator", - "kotlin.collections.MutableSet" to "isMutableSet", - "kotlin.collections.MutableMap" to "isMutableMap", - "kotlin.collections.MutableMap.MutableEntry" to "isMutableMapEntry" + + private val MUTABLE_COLLECTION_TYPE_FQ_NAMES = setOf( + FQ_NAMES.mutableIterator, + FQ_NAMES.mutableIterable, + FQ_NAMES.mutableCollection, + FQ_NAMES.mutableList, + FQ_NAMES.mutableListIterator, + FQ_NAMES.mutableMap, + FQ_NAMES.mutableSet, + FQ_NAMES.mutableMapEntry ) + private fun getMutableCollectionMethodName(prefix: String, jetType: KotlinType): String? { + val fqName = getClassFqName(jetType) + if (fqName == null || fqName !in MUTABLE_COLLECTION_TYPE_FQ_NAMES) return null + val baseName = if (fqName == FQ_NAMES.mutableMapEntry) "MutableMapEntry" else fqName.shortName().asString() + return prefix + baseName + } + + private fun getIsMutableCollectionMethodName(jetType: KotlinType): String? = getMutableCollectionMethodName("is", jetType) + + private fun getAsMutableCollectionMethodName(jetType: KotlinType): String? = getMutableCollectionMethodName("as", jetType) + private val IS_MUTABLE_COLLECTION_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getObjectType("java/lang/Object")) - private fun getClassFqName(jetType: KotlinType): String? { + private fun getClassFqName(jetType: KotlinType): FqName? { val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null - return DescriptorUtils.getFqName(classDescriptor).asString() + return DescriptorUtils.getFqName(classDescriptor).toSafe() } private val KOTLIN_FUNCTION_INTERFACE_REGEX = Regex("^kotlin\\.Function([0-9]+)$") @@ -140,7 +154,7 @@ object TypeIntrinsics { */ private fun getFunctionTypeArity(jetType: KotlinType): Int { val classFqName = getClassFqName(jetType) ?: return -1 - val match = KOTLIN_FUNCTION_INTERFACE_REGEX.find(classFqName) ?: return -1 + val match = KOTLIN_FUNCTION_INTERFACE_REGEX.find(classFqName.asString()) ?: return -1 return Integer.valueOf(match.groups[1]!!.value) } @@ -151,25 +165,6 @@ object TypeIntrinsics { invokestatic(INTRINSICS_CLASS, methodName, methodDescriptor, false) } - private fun getIsMutableCollectionMethodName(jetType: KotlinType): String? = - IS_MUTABLE_COLLECTION_METHOD_NAME[getClassFqName(jetType)] - - private val CHECKCAST_METHOD_NAME = hashMapOf( - "kotlin.collections.MutableIterator" to "asMutableIterator", - "kotlin.collections.MutableIterable" to "asMutableIterable", - "kotlin.collections.MutableCollection" to "asMutableCollection", - "kotlin.collections.MutableList" to "asMutableList", - "kotlin.collections.MutableListIterator" to "asMutableListIterator", - "kotlin.collections.MutableSet" to "asMutableSet", - "kotlin.collections.MutableMap" to "asMutableMap", - "kotlin.collections.MutableMap.MutableEntry" to "asMutableMapEntry" - ) - - private fun getAsMutableCollectionMethodName(jetType: KotlinType): String? { - val classDescriptor = TypeUtils.getClassDescriptor(jetType) ?: return null - val classFqName = DescriptorUtils.getFqName(classDescriptor).asString() - return CHECKCAST_METHOD_NAME[classFqName] - } private val OBJECT_TYPE = Type.getObjectType("java/lang/Object") diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index 22460e17fbd..77b605a64c4 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -162,14 +162,18 @@ public abstract class KotlinBuiltIns { public final FqName iterable = collectionsFqName("Iterable"); public final FqName collection = collectionsFqName("Collection"); public final FqName list = collectionsFqName("List"); + public final FqName listIterator = collectionsFqName("ListIterator"); public final FqName set = collectionsFqName("Set"); public final FqName map = collectionsFqName("Map"); + public final FqName mapEntry = map.child(Name.identifier("Entry")); public final FqName mutableIterator = collectionsFqName("MutableIterator"); public final FqName mutableIterable = collectionsFqName("MutableIterable"); public final FqName mutableCollection = collectionsFqName("MutableCollection"); public final FqName mutableList = collectionsFqName("MutableList"); + public final FqName mutableListIterator = collectionsFqName("MutableListIterator"); public final FqName mutableSet = collectionsFqName("MutableSet"); public final FqName mutableMap = collectionsFqName("MutableMap"); + public final FqName mutableMapEntry = mutableMap.child(Name.identifier("MutableEntry")); private final FqNameUnsafe _collection = collection.toUnsafe(); private final FqNameUnsafe _list = list.toUnsafe(); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java index 44229280200..704066762c9 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.types.KotlinType; import java.util.List; +import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES; import static org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern; import static org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic.CallParametersAwareFunctionIntrinsic; import static org.jetbrains.kotlin.js.translate.utils.ManglingUtils.getStableMangledNameForDescriptor; @@ -138,17 +139,17 @@ public final class TopLevelFIF extends CompositeFIF { private TopLevelFIF() { add(EQUALS_IN_ANY, KOTLIN_EQUALS); - add(pattern("kotlin", "toString").isExtensionOf("kotlin.Any"), TO_STRING); - add(pattern("kotlin", "equals").isExtensionOf("kotlin.Any"), KOTLIN_EQUALS); + add(pattern("kotlin", "toString").isExtensionOf(FQ_NAMES.any.asString()), TO_STRING); + add(pattern("kotlin", "equals").isExtensionOf(FQ_NAMES.any.asString()), KOTLIN_EQUALS); add(pattern("kotlin", "identityEquals").isExtensionOf("kotlin.Any"), IDENTITY_EQUALS); add(HASH_CODE_IN_ANY, KOTLIN_HASH_CODE); add(pattern(NamePredicate.PRIMITIVE_NUMBERS, "equals"), KOTLIN_EQUALS); add(pattern("String|Boolean|Char|Number.equals"), KOTLIN_EQUALS); add(pattern("kotlin", "arrayOfNulls"), new KotlinFunctionIntrinsic("nullArray")); - add(pattern("kotlin", "iterator").isExtensionOf("kotlin.Iterator"), RETURN_RECEIVER_INTRINSIC); + add(pattern("kotlin", "iterator").isExtensionOf(FQ_NAMES.iterator.asString()), RETURN_RECEIVER_INTRINSIC); add(pattern("kotlin.collections", "Map", "get").checkOverridden(), NATIVE_MAP_GET); - add(pattern("kotlin.js", "set").isExtensionOf("kotlin.collections.MutableMap"), NATIVE_MAP_SET); + add(pattern("kotlin.js", "set").isExtensionOf(FQ_NAMES.mutableMap.asString()), NATIVE_MAP_SET); add(pattern("java.util", "HashMap", ""), new MapSelectImplementationIntrinsic(false)); add(pattern("java.util", "HashSet", ""), new MapSelectImplementationIntrinsic(true));