diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt index 706fabd4f2e..5a610f0d868 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt @@ -21,12 +21,11 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaStaticClassScope +import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor -import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.types.KotlinType fun copyValueParameters( @@ -34,7 +33,7 @@ fun copyValueParameters( oldValueParameters: Collection, newOwner: CallableDescriptor ): List { - assert(newValueParametersTypes.size() == oldValueParameters.size()) { + assert(newValueParametersTypes.size == oldValueParameters.size) { "Different value parameters sizes: Enhanced = ${newValueParametersTypes.size}, Old = ${oldValueParameters.size}" } @@ -45,14 +44,14 @@ fun copyValueParameters( newOwner, oldParameter, oldParameter.index, - oldParameter.getAnnotations(), - oldParameter.getName(), + oldParameter.annotations, + oldParameter.name, newType, oldParameter.declaresDefaultValue(), oldParameter.isCrossinline, oldParameter.isNoinline, if (oldParameter.varargElementType != null) newOwner.module.builtIns.getArrayElementType(newType) else null, - oldParameter.getSource() + oldParameter.source ) } } @@ -68,19 +67,5 @@ fun ClassDescriptor.getParentJavaStaticClassScope(): LazyJavaStaticClassScope? { } fun DeserializedCallableMemberDescriptor.getImplClassNameForDeserialized(): Name? { - val proto = proto - return when (proto) { - is ProtoBuf.Constructor -> - null - is ProtoBuf.Function -> - if (proto.hasExtension(JvmProtoBuf.methodImplClassName)) - proto.getExtension(JvmProtoBuf.methodImplClassName) - else null - is ProtoBuf.Property -> - if (proto.hasExtension(JvmProtoBuf.propertyImplClassName)) - proto.getExtension(JvmProtoBuf.propertyImplClassName) - else null - else -> - error("Unknown message: $proto") - }?.let { nameResolver.getName(it) } + return (packagePartSource as? JvmPackagePartSource)?.className?.fqNameForClassNameWithoutDollars?.shortName() } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt index f2e2c82a02a..24ecab7e72b 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt @@ -21,13 +21,13 @@ import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.* import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf -import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.* +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.index +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertySignature import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.KotlinType @@ -95,26 +95,26 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader - findClassAndLoadMemberAnnotations(container, proto, sig) + findClassAndLoadMemberAnnotations(container, sig, property = true) }.orEmpty() val fieldAnnotations = fieldSignature?.let { sig -> - findClassAndLoadMemberAnnotations(container, proto, sig, field = true) + findClassAndLoadMemberAnnotations(container, sig, property = true, field = true) }.orEmpty() return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations) } val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, kind) ?: return emptyList() - return transformAnnotations(findClassAndLoadMemberAnnotations(container, proto, signature)) + return transformAnnotations(findClassAndLoadMemberAnnotations(container, signature)) } override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List { val signature = MemberSignature.fromFieldNameAndDesc( container.nameResolver.getString(proto.name), - ClassMapperLite.mapClass(container.nameResolver.getClassId((container as ProtoContainer.Class).classProto.fqName)) + ClassMapperLite.mapClass((container as ProtoContainer.Class).classId) ) - return findClassAndLoadMemberAnnotations(container, proto, signature) + return findClassAndLoadMemberAnnotations(container, signature) } protected abstract fun loadPropertyAnnotations(propertyAnnotations: List, fieldAnnotations: List): List @@ -122,13 +122,10 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader): List private fun findClassAndLoadMemberAnnotations( - container: ProtoContainer, proto: MessageLite, signature: MemberSignature, field: Boolean = false + container: ProtoContainer, signature: MemberSignature, property: Boolean = false, field: Boolean = false ): List { - val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(proto, container.nameResolver), field) - if (kotlinClass == null) { - errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: ${container.debugFqName()}", null) - return listOf() - } + val kotlinClass = findClassWithAnnotationsAndInitializers(container, getImplClassName(container, property), field) + ?: return listOf() return storage(kotlinClass).memberAnnotations[signature] ?: listOf() } @@ -144,7 +141,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader { - implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(container.fqName, it)) } + container: ProtoContainer, implClassName: ClassId?, field: Boolean + ): KotlinJvmBinaryClass? { + if (implClassName != null) { + return kotlinClassFinder.findKotlinClass(implClassName) } - is ProtoContainer.Class -> { - val classId = container.nameResolver.getClassId(container.classProto.fqName) - if (implClassName != null) { - // TODO: store accurate name for nested traits - val implClassId = - if (implClassName.asString().endsWith(JvmAbi.DEFAULT_IMPLS_SUFFIX)) - ClassId(classId.packageFqName, FqName(implClassName.asString().replace(JvmAbi.DEFAULT_IMPLS_SUFFIX, "." + JvmAbi.DEFAULT_IMPLS_CLASS_NAME)), false) - else - ClassId(classId.packageFqName, implClassName) - kotlinClassFinder.findKotlinClass(implClassId) - } - else if (field && container.isCompanionOfClass) { + if (container is ProtoContainer.Class) { + if (field && container.isCompanionOfClass) { // Backing fields of properties of a companion object in a class are generated in the outer class - kotlinClassFinder.findKotlinClass(classId.outerClassId) - } - else { - kotlinClassFinder.findKotlinClass(classId) + return kotlinClassFinder.findKotlinClass(container.classId.outerClassId) } + + return kotlinClassFinder.findKotlinClass(container.classId) } + + return null } - private fun getImplClassName(proto: MessageLite, nameResolver: NameResolver): Name? = - when { - proto is ProtoBuf.Function && proto.hasExtension(methodImplClassName) -> - nameResolver.getName(proto.getExtension(methodImplClassName)) - proto is ProtoBuf.Property && proto.hasExtension(propertyImplClassName) -> - nameResolver.getName(proto.getExtension(propertyImplClassName)) - else -> null - } + private fun getImplClassName(container: ProtoContainer, property: Boolean): ClassId? { + if (property && container is ProtoContainer.Class && container.isInterface) { + return container.classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)) + } + return ((container as? ProtoContainer.Package)?.packagePartSource as? JvmPackagePartSource) + ?.className?.fqNameForClassNameWithoutDollars?.let { ClassId.topLevel(it) } + } private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage { val memberAnnotations = HashMap>() diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt index feff5369c51..49ef944bbe9 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt @@ -248,7 +248,8 @@ public class MemberDeserializer(private val c: DeserializationContext) { is DeserializedClassDescriptor -> ProtoContainer.Class( classProto, c.nameResolver, c.typeTable, isCompanionOfClass = DescriptorUtils.isCompanionObject(this) && - containingDeclaration.let { DescriptorUtils.isClass(it) || DescriptorUtils.isEnumClass(it) } + containingDeclaration.let { DescriptorUtils.isClass(it) || DescriptorUtils.isEnumClass(it) }, + isInterface = kind == ClassKind.INTERFACE ) else -> null // TODO: support annotations on lambdas and their parameters } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoContainer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoContainer.kt index 1050da9ca79..bb6908c3371 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoContainer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoContainer.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.serialization.deserialization +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.descriptors.PackagePartSource @@ -28,9 +29,12 @@ sealed class ProtoContainer( val classProto: ProtoBuf.Class, nameResolver: NameResolver, typeTable: TypeTable, - val isCompanionOfClass: Boolean + val isCompanionOfClass: Boolean, + val isInterface: Boolean ) : ProtoContainer(nameResolver, typeTable) { - override fun debugFqName(): FqName = nameResolver.getClassId(classProto.fqName).asSingleFqName() + val classId: ClassId = nameResolver.getClassId(classProto.fqName) + + override fun debugFqName(): FqName = classId.asSingleFqName() } class Package( diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 77b659b9a40..775a81e1531 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -296,7 +296,8 @@ public class DeserializedClassDescriptor( val annotations = enumEntryProtos[name]?.let { proto -> DeserializedAnnotations(c.storageManager) { c.components.annotationAndConstantLoader.loadEnumEntryAnnotations( - ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false), proto + ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false, isInterface = false), + proto ) } } ?: if (name in oldEnumEntryNames) Annotations.EMPTY diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt index 4c48a53dc90..844837db89e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClassClsStubBuilder.kt @@ -68,6 +68,7 @@ private class ClassClsStubBuilder( return classKind == ProtoBuf.Class.Kind.COMPANION_OBJECT && (outerContext.classKind?.let { it == ProtoBuf.Class.Kind.CLASS || it == ProtoBuf.Class.Kind.ENUM_CLASS } ?: false) } + private val isInterface: Boolean get() = classKind == ProtoBuf.Class.Kind.INTERFACE private val classOrObjectStub = createClassOrObjectStubAndModifierListStub() @@ -142,7 +143,7 @@ private class ClassClsStubBuilder( val primaryConstructorProto = classProto.constructorList.find { !Flags.IS_SECONDARY.get(it.flags) } ?: return createConstructorStub(classOrObjectStub, primaryConstructorProto, c, - ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass)) + ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass, isInterface)) } private fun createDelegationSpecifierList() { @@ -180,7 +181,7 @@ private class ClassClsStubBuilder( private fun createEnumEntryStubs(classBody: KotlinPlaceHolderStubImpl) { if (classKind != ProtoBuf.Class.Kind.ENUM_CLASS) return - val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false) + val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass, isInterface) val enumEntries: List>> = if (classProto.enumEntryList.isNotEmpty()) classProto.enumEntryList.map { enumEntryProto -> @@ -211,7 +212,7 @@ private class ClassClsStubBuilder( } private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl) { - val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass) + val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass, isInterface) for (secondaryConstructorProto in classProto.constructorList) { if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) {