diff --git a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinSuperTypeListBuilder.kt b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinSuperTypeListBuilder.kt index d4bb588031c..d8c54a2113b 100644 --- a/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinSuperTypeListBuilder.kt +++ b/analysis/light-classes-base/src/org/jetbrains/kotlin/asJava/classes/KotlinSuperTypeListBuilder.kt @@ -10,6 +10,8 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiJavaCodeReferenceElement import com.intellij.psi.PsiManager import com.intellij.psi.PsiReferenceList +import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.psi.KtSuperTypeList import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext @@ -54,4 +56,25 @@ class KotlinSuperTypeListBuilder(kotlinOrigin: KtSuperTypeList?, manager: PsiMan return element } + + fun addMarkerInterfaceIfNeeded(classId: ClassId) { + tryResolveMarkerInterfaceFQName(classId)?.let { addReference(it) } + } + + /*** + * @see org.jetbrains.kotlin.codegen.ImplementationBodyCodegen + */ + private fun tryResolveMarkerInterfaceFQName(classId: ClassId): String? { + for (mapping in JavaToKotlinClassMap.mutabilityMappings) { + if (mapping.kotlinReadOnly == classId) { + return "kotlin.jvm.internal.markers.KMappedMarker" + } else if (mapping.kotlinMutable == classId) { + return "kotlin.jvm.internal.markers.K" + classId.relativeClassName.asString() + .replace("MutableEntry", "Entry") // kotlin.jvm.internal.markers.KMutableMap.Entry for some reason + .replace(".", "$") + } + } + + return null + } } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt index 18a000a46de..16f5ee41a93 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt @@ -416,14 +416,26 @@ internal fun SymbolLightClassBase.createInheritanceList(forExtendsList: Boolean, return forExtendsList == !isJvmInterface } - //TODO Add support for kotlin.collections. superTypes.asSequence() .filter { it.needToAddTypeIntoList() } - .mapNotNull { type -> - if (type !is KtNonErrorClassType) return@mapNotNull null - mapType(type, this@createInheritanceList, KtTypeMappingMode.SUPER_TYPE) + .forEach { superType -> + if (superType !is KtNonErrorClassType) return@forEach + val mappedType = + mapType(superType, this@createInheritanceList, KtTypeMappingMode.SUPER_TYPE_KOTLIN_COLLECTIONS_AS_IS) + ?: return@forEach + listBuilder.addReference(mappedType) + if (mappedType.canonicalText.startsWith("kotlin.collections.")) { + val mappedToNoCollectionAsIs = mapType(superType, this@createInheritanceList, KtTypeMappingMode.SUPER_TYPE) + if (mappedToNoCollectionAsIs != null && + mappedType.canonicalText != mappedToNoCollectionAsIs.canonicalText + ) { + // Add java supertype + listBuilder.addReference(mappedToNoCollectionAsIs) + // Add marker interface + listBuilder.addMarkerInterfaceIfNeeded(superType.classId) + } + } } - .forEach { listBuilder.addReference(it) } return listBuilder } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt index f8519726434..01e920cb8c9 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.EnumValue +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny @@ -143,8 +144,8 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor //Add java supertype listBuilder.addReference(mappedToNoCollectionAsIs) //Add marker interface - superType.tryResolveMarkerInterfaceFQName()?.let { marker -> - listBuilder.addReference(marker) + superType.constructor.declarationDescriptor.classId?.let { classId -> + listBuilder.addMarkerInterfaceIfNeeded(classId) } } } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt index d3f8246b887..87e618f1783 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.elements.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.StandardNames -import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.codegen.DescriptorAsmUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.OwnerKind @@ -48,7 +47,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.* -import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.resolve.source.KotlinSourceElement @@ -516,27 +514,6 @@ private fun ConstantValue<*>.asStringForPsiLiteral(parent: PsiElement): String = } } - -/*** - * @see org.jetbrains.kotlin.codegen.ImplementationBodyCodegen - */ -fun KotlinType.tryResolveMarkerInterfaceFQName(): String? { - - val classId = constructor.declarationDescriptor.classId - - for (mapping in JavaToKotlinClassMap.mutabilityMappings) { - if (mapping.kotlinReadOnly == classId) { - return "kotlin.jvm.internal.markers.KMappedMarker" - } else if (mapping.kotlinMutable == classId) { - return "kotlin.jvm.internal.markers.K" + classId.relativeClassName.asString() - .replace("MutableEntry", "Entry") // kotlin.jvm.internal.markers.KMutableMap.Entry for some reason - .replace(".", "$") - } - } - - return null -} - internal inline fun Project.applyCompilerPlugins(body: (UltraLightClassModifierExtension) -> Unit) { UltraLightClassModifierExtension.getInstances(this).forEach { body(it) } } diff --git a/compiler/testData/asJava/lightClasses/compilationErrors/TwoOverrides.fir.java b/compiler/testData/asJava/lightClasses/compilationErrors/TwoOverrides.fir.java index 614e3c692df..6cacc5de1af 100644 --- a/compiler/testData/asJava/lightClasses/compilationErrors/TwoOverrides.fir.java +++ b/compiler/testData/asJava/lightClasses/compilationErrors/TwoOverrides.fir.java @@ -1,4 +1,4 @@ -public final class TwoOverrides /* TwoOverrides*/ implements java.lang.Iterable { +public final class TwoOverrides /* TwoOverrides*/ implements java.lang.Iterable, kotlin.collections.Iterable, kotlin.jvm.internal.markers.KMappedMarker { @java.lang.Override() @org.jetbrains.annotations.Nullable() public java.lang.Void iterator();// iterator() diff --git a/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.fir.java b/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.fir.java index ccc9d77fc93..d248ba14ce3 100644 --- a/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.fir.java +++ b/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMap.fir.java @@ -1,4 +1,4 @@ -public final class TypeHierarchyMap /* p1.TypeHierarchyMap*/ implements java.util.Map, TValue> { +public final class TypeHierarchyMap /* p1.TypeHierarchyMap*/ implements java.util.Map, TValue>, kotlin.collections.Map, TValue>, kotlin.jvm.internal.markers.KMappedMarker { @java.lang.Override() public boolean containsKey(@org.jetbrains.annotations.NotNull() java.lang.Class);// containsKey(java.lang.Class) diff --git a/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMutableSet.fir.java b/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMutableSet.fir.java index 83fafa1cff2..d0eedb9aba6 100644 --- a/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMutableSet.fir.java +++ b/compiler/testData/asJava/lightClasses/ideRegression/ImplementingMutableSet.fir.java @@ -1,4 +1,4 @@ -public final class SmartSet /* SmartSet*/ extends kotlin.collections.AbstractSet implements java.util.Set { +public final class SmartSet /* SmartSet*/ extends kotlin.collections.AbstractSet implements java.util.Set, kotlin.collections.MutableSet, kotlin.jvm.internal.markers.KMutableSet { @org.jetbrains.annotations.NotNull() public static final SmartSet.Companion Companion; diff --git a/compiler/testData/asJava/ultraLightClasses/implementingKotlinCollections.fir.java b/compiler/testData/asJava/ultraLightClasses/implementingKotlinCollections.fir.java index 7f88726f982..a72d3becbf7 100644 --- a/compiler/testData/asJava/ultraLightClasses/implementingKotlinCollections.fir.java +++ b/compiler/testData/asJava/ultraLightClasses/implementingKotlinCollections.fir.java @@ -1,4 +1,4 @@ -public final class MyList /* MyList*/ implements java.util.List { +public final class MyList /* MyList*/ implements java.util.List, kotlin.collections.List, kotlin.jvm.internal.markers.KMappedMarker { @java.lang.Override() @org.jetbrains.annotations.NotNull() public java.lang.String get(int);// get(int) @@ -7,7 +7,7 @@ public final class MyList /* MyList*/ implements java.util.List extends java.util.Collection { +public abstract interface ASet /* ASet*/ extends java.util.Collection, kotlin.collections.MutableCollection, kotlin.jvm.internal.markers.KMutableCollection { } public abstract class MySet /* MySet*/ implements ASet {