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 ae29b8ce415..f2e2c82a02a 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
@@ -91,16 +91,15 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader
findClassAndLoadMemberAnnotations(container, proto, sig)
}.orEmpty()
val fieldAnnotations = fieldSignature?.let { sig ->
- findClassAndLoadMemberAnnotations(container, proto, sig, isStaticFieldInOuter(proto))
+ findClassAndLoadMemberAnnotations(container, proto, sig, field = true)
}.orEmpty()
return loadPropertyAnnotations(propertyAnnotations, fieldAnnotations)
@@ -123,14 +122,9 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader): List
private fun findClassAndLoadMemberAnnotations(
- container: ProtoContainer,
- proto: MessageLite,
- signature: MemberSignature,
- isStaticFieldInOuter: Boolean = false
+ container: ProtoContainer, proto: MessageLite, signature: MemberSignature, field: Boolean = false
): List {
- val kotlinClass = findClassWithAnnotationsAndInitializers(
- container, getImplClassName(proto, container.nameResolver), isStaticFieldInOuter
- )
+ 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()
@@ -182,9 +176,7 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader {
implClassName?.let { kotlinClassFinder.findKotlinClass(ClassId(container.fqName, it)) }
@@ -211,8 +203,8 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader null
}
- private fun isStaticFieldInOuter(proto: MessageLite): Boolean =
- if (proto is ProtoBuf.Property && proto.hasExtension(propertySignature))
- proto.getExtension(propertySignature).let { it.hasField() && it.field.isStaticInOuter }
- else false
-
private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): Storage {
val memberAnnotations = HashMap>()
val propertyConstants = 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 6edcb355bd6..6f43be3241c 100644
--- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt
+++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.resolve.DescriptorFactory
+import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.serialization.Flags
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
@@ -241,9 +242,13 @@ public class MemberDeserializer(private val c: DeserializationContext) {
}
}
- private fun DeclarationDescriptor.asProtoContainer(): ProtoContainer? = when(this) {
+ private fun DeclarationDescriptor.asProtoContainer(): ProtoContainer? = when (this) {
is PackageFragmentDescriptor -> ProtoContainer.Package(fqName, c.nameResolver, c.typeTable)
- is DeserializedClassDescriptor -> ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
+ is DeserializedClassDescriptor -> ProtoContainer.Class(
+ classProto, c.nameResolver, c.typeTable,
+ isCompanionOfClass = DescriptorUtils.isCompanionObject(this) &&
+ containingDeclaration.let { DescriptorUtils.isClass(it) || DescriptorUtils.isEnumClass(it) }
+ )
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 c0947d1854c..10353e6d29c 100644
--- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoContainer.kt
+++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/ProtoContainer.kt
@@ -26,7 +26,8 @@ sealed class ProtoContainer(
class Class(
val classProto: ProtoBuf.Class,
nameResolver: NameResolver,
- typeTable: TypeTable
+ typeTable: TypeTable,
+ val isCompanionOfClass: Boolean
) : ProtoContainer(nameResolver, typeTable) {
override fun debugFqName(): FqName = nameResolver.getClassId(classProto.fqName).asSingleFqName()
}
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 8042e67bfb4..77b659b9a40 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,7 @@ public class DeserializedClassDescriptor(
val annotations = enumEntryProtos[name]?.let { proto ->
DeserializedAnnotations(c.storageManager) {
c.components.annotationAndConstantLoader.loadEnumEntryAnnotations(
- ProtoContainer.Class(classProto, c.nameResolver, c.typeTable), proto
+ ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = 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 f0c5642f388..4c48a53dc90 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
@@ -50,9 +50,9 @@ private class ClassClsStubBuilder(
private val classId: ClassId,
private val outerContext: ClsStubBuilderContext
) {
- private val c = outerContext.child(classProto.typeParameterList, classId.shortClassName, TypeTable(classProto.typeTable))
- private val typeStubBuilder = TypeClsStubBuilder(c)
private val classKind = Flags.CLASS_KIND[classProto.flags]
+ private val c = outerContext.child(classProto.typeParameterList, classKind, classId.shortClassName, TypeTable(classProto.typeTable))
+ private val typeStubBuilder = TypeClsStubBuilder(c)
private val supertypeIds = run {
val supertypeIds = classProto.supertypes(c.typeTable).map { c.nameResolver.getClassId(it.className) }
//empty supertype list if single supertype is Any
@@ -64,6 +64,10 @@ private class ClassClsStubBuilder(
}
}
private val companionObjectName = if (classProto.hasCompanionObjectName()) c.nameResolver.getName(classProto.getCompanionObjectName()) else null
+ private val isCompanionOfClass: Boolean get() {
+ return classKind == ProtoBuf.Class.Kind.COMPANION_OBJECT &&
+ (outerContext.classKind?.let { it == ProtoBuf.Class.Kind.CLASS || it == ProtoBuf.Class.Kind.ENUM_CLASS } ?: false)
+ }
private val classOrObjectStub = createClassOrObjectStubAndModifierListStub()
@@ -137,7 +141,8 @@ 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))
+ createConstructorStub(classOrObjectStub, primaryConstructorProto, c,
+ ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass))
}
private fun createDelegationSpecifierList() {
@@ -175,7 +180,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)
+ val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass = false)
val enumEntries: List>> =
if (classProto.enumEntryList.isNotEmpty())
classProto.enumEntryList.map { enumEntryProto ->
@@ -206,7 +211,7 @@ private class ClassClsStubBuilder(
}
private fun createCallableMemberStubs(classBody: KotlinPlaceHolderStubImpl) {
- val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable)
+ val container = ProtoContainer.Class(classProto, c.nameResolver, c.typeTable, isCompanionOfClass)
for (secondaryConstructorProto in classProto.constructorList) {
if (Flags.IS_SECONDARY.get(secondaryConstructorProto.flags)) {
diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt
index 1ff45275054..72022f18a4e 100644
--- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt
+++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderContext.kt
@@ -39,7 +39,7 @@ class ClsStubBuilderComponents(
packageFqName: FqName,
typeTable: TypeTable
): ClsStubBuilderContext {
- return ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable)
+ return ClsStubBuilderContext(this, nameResolver, packageFqName, EmptyTypeParameters, typeTable, classKind = null)
}
}
@@ -69,11 +69,13 @@ class ClsStubBuilderContext(
val nameResolver: NameResolver,
val containerFqName: FqName,
val typeParameters: TypeParameters,
- val typeTable: TypeTable
+ val typeTable: TypeTable,
+ val classKind: ProtoBuf.Class.Kind?
)
internal fun ClsStubBuilderContext.child(
typeParameterList: List,
+ classKind: ProtoBuf.Class.Kind? = null,
name: Name? = null,
typeTable: TypeTable = this.typeTable
): ClsStubBuilderContext {
@@ -82,7 +84,8 @@ internal fun ClsStubBuilderContext.child(
this.nameResolver,
if (name != null) this.containerFqName.child(name) else this.containerFqName,
this.typeParameters.child(nameResolver, typeParameterList),
- typeTable
+ typeTable,
+ classKind
)
}
@@ -92,6 +95,7 @@ internal fun ClsStubBuilderContext.child(nameResolver: NameResolver, typeTable:
nameResolver,
this.containerFqName,
this.typeParameters,
- typeTable
+ typeTable,
+ classKind = null
)
}
diff --git a/idea/testData/decompiler/stubBuilder/Annotations/Annotations.kt b/idea/testData/decompiler/stubBuilder/Annotations/Annotations.kt
index cae3f43fee6..51fce783b2f 100644
--- a/idea/testData/decompiler/stubBuilder/Annotations/Annotations.kt
+++ b/idea/testData/decompiler/stubBuilder/Annotations/Annotations.kt
@@ -17,7 +17,7 @@
private @b(E.E2) companion object {
-
+ @f val field = 42
}
class Nested @a private @b(E.E1) @b(E.E2) constructor()
@@ -43,4 +43,7 @@ annotation class b(val e: E)
AnnotationTarget.TYPE, AnnotationTarget.CLASS)
annotation class c
+@Target(AnnotationTarget.FIELD)
+annotation class f
+
enum class E { E1, E2 }
diff --git a/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt b/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt
index 8c99fd45505..1e8e65b3ee0 100644
--- a/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt
+++ b/idea/testData/decompiler/stubBuilder/Annotations/Annotations.txt
@@ -44,6 +44,19 @@ PsiJetFileStubImpl[package=]
OBJECT_DECLARATION:[fqName=Annotations.Companion, isCompanion=true, isLocal=false, isObjectLiteral=false, isTopLevel=false, name=Companion, superNames=[]]
MODIFIER_LIST:[private companion]
CLASS_BODY:
+ PROPERTY:[fqName=Annotations.Companion.field, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=field]
+ MODIFIER_LIST:[public final]
+ ANNOTATION_ENTRY:[hasValueArguments=false, shortName=f]
+ ANNOTATION_TARGET:[useSiteTarget=FIELD]
+ CONSTRUCTOR_CALLEE:
+ TYPE_REFERENCE:
+ USER_TYPE:[isAbsoluteInRootPackage=false]
+ REFERENCE_EXPRESSION:[referencedName=f]
+ TYPE_REFERENCE:
+ USER_TYPE:[isAbsoluteInRootPackage=false]
+ USER_TYPE:[isAbsoluteInRootPackage=false]
+ REFERENCE_EXPRESSION:[referencedName=kotlin]
+ REFERENCE_EXPRESSION:[referencedName=Int]
PROPERTY:[fqName=Annotations.c, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=c]
MODIFIER_LIST:[private final]
TYPE_REFERENCE: