diff --git a/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/AnnotationLoaderForStubBuilderImpl.kt b/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/AnnotationLoaderForStubBuilderImpl.kt index a7e901fce90..76975d8d7ba 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/AnnotationLoaderForStubBuilderImpl.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/AnnotationLoaderForStubBuilderImpl.kt @@ -5,25 +5,27 @@ package org.jetbrains.kotlin.analysis.decompiler.stub.file +import org.jetbrains.kotlin.analysis.decompiler.stub.AnnotationWithArgs import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.NameResolver -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.protobuf.MessageLite +import org.jetbrains.kotlin.psi.stubs.impl.createConstantValue import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol import org.jetbrains.kotlin.serialization.deserialization.* class AnnotationLoaderForStubBuilderImpl( private val protocol: SerializerExtensionProtocol -) : AnnotationLoader { +) : AnnotationLoader { - override fun loadClassAnnotations(container: ProtoContainer.Class): List = - container.classProto.getExtension(protocol.classAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) } + override fun loadClassAnnotations(container: ProtoContainer.Class): List = + container.classProto.getExtension(protocol.classAnnotation).orEmpty() + .map { loadAnnotation(it, container.nameResolver) } override fun loadCallableAnnotations( container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind - ): List { + ): List { val annotations = when (proto) { is ProtoBuf.Constructor -> proto.getExtension(protocol.constructorAnnotation) is ProtoBuf.Function -> proto.getExtension(protocol.functionAnnotation) @@ -35,17 +37,17 @@ class AnnotationLoaderForStubBuilderImpl( } else -> error("Unknown message: $proto") }.orEmpty() - return annotations.map { container.nameResolver.getClassId(it.id) } + return annotations.map { loadAnnotation(it, container.nameResolver) } } - override fun loadPropertyBackingFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = + override fun loadPropertyBackingFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = emptyList() - override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = + override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List = emptyList() - override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List = - proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) } + override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List = + proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { loadAnnotation(it, container.nameResolver) } override fun loadValueParameterAnnotations( container: ProtoContainer, @@ -53,21 +55,26 @@ class AnnotationLoaderForStubBuilderImpl( kind: AnnotatedCallableKind, parameterIndex: Int, proto: ProtoBuf.ValueParameter - ): List = - proto.getExtension(protocol.parameterAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) } + ): List = + proto.getExtension(protocol.parameterAnnotation).orEmpty().map { loadAnnotation(it, container.nameResolver) } override fun loadExtensionReceiverParameterAnnotations( container: ProtoContainer, proto: MessageLite, kind: AnnotatedCallableKind - ): List = emptyList() + ): List = emptyList() override fun loadTypeAnnotations( proto: ProtoBuf.Type, nameResolver: NameResolver - ): List = - proto.getExtension(protocol.typeAnnotation).orEmpty().map { nameResolver.getClassId(it.id) } + ): List = + proto.getExtension(protocol.typeAnnotation).orEmpty().map { loadAnnotation(it, nameResolver) } - override fun loadTypeParameterAnnotations(proto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List = - proto.getExtension(protocol.typeParameterAnnotation).orEmpty().map { nameResolver.getClassId(it.id) } + override fun loadTypeParameterAnnotations(proto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List = + proto.getExtension(protocol.typeParameterAnnotation).orEmpty().map { loadAnnotation(it, nameResolver) } + + override fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationWithArgs { + val valueMap = proto.argumentList.associate { nameResolver.getName(it.nameId) to createConstantValue(it.value, nameResolver) } + return AnnotationWithArgs(nameResolver.getClassId(proto.id), valueMap) + } } diff --git a/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt b/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt index ace8693057f..d48d578543c 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/file/KotlinClsStubBuilder.kt @@ -13,6 +13,8 @@ import com.intellij.psi.stubs.PsiFileStub import com.intellij.util.indexing.FileContent import org.jetbrains.kotlin.SpecialJvmAnnotations import org.jetbrains.kotlin.analysis.decompiler.stub.* +import org.jetbrains.kotlin.constant.ConstantValue +import org.jetbrains.kotlin.constant.KClassValue import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.* @@ -28,11 +30,11 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.stubs.KotlinStubVersions -import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue -import org.jetbrains.kotlin.resolve.constants.ConstantValue -import org.jetbrains.kotlin.resolve.constants.KClassValue +import org.jetbrains.kotlin.psi.stubs.impl.createConstantValue import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol + import org.jetbrains.kotlin.serialization.deserialization.getClassId +import org.jetbrains.kotlin.serialization.deserialization.getName import org.jetbrains.kotlin.storage.LockBasedStorageManager open class KotlinClsStubBuilder : ClsStubBuilder() { @@ -135,14 +137,16 @@ private class AnnotationLoaderForClassFileStubBuilder( private val cachedFile: VirtualFile, private val cachedFileContent: ByteArray, override val jvmMetadataVersion: JvmMetadataVersion -) : AbstractBinaryClassAnnotationLoader(kotlinClassFinder) { +) : AbstractBinaryClassAnnotationLoader>>( + kotlinClassFinder +) { private val storage = - LockBasedStorageManager.NO_LOCKS.createMemoizedFunction { kotlinClass -> + LockBasedStorageManager.NO_LOCKS.createMemoizedFunction>> { kotlinClass -> loadAnnotationsAndInitializers(kotlinClass) } - override fun getAnnotationsContainer(binaryClass: KotlinJvmBinaryClass): AnnotationsClassIdContainer { + override fun getAnnotationsContainer(binaryClass: KotlinJvmBinaryClass): AnnotationsContainerWithConstants> { return storage(binaryClass) } @@ -153,34 +157,20 @@ private class AnnotationLoaderForClassFileStubBuilder( return null } - override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = nameResolver.getClassId(proto.id) - + override fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationWithArgs { + val args = proto.argumentList.associate { nameResolver.getName(it.nameId) to createConstantValue(it.value, nameResolver) } + return AnnotationWithArgs(nameResolver.getClassId(proto.id), args) + } override fun loadAnnotation( - annotationClassId: ClassId, source: SourceElement, result: MutableList - ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { - if (annotationClassId != SpecialJvmAnnotations.JAVA_LANG_ANNOTATION_REPEATABLE) { - result += annotationClassId - return null - } - - return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor { - private val arguments = mutableMapOf>() - override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) { - if (name != null) - arguments[name] = KClassValue(value) - } - + annotationClassId: ClassId, source: SourceElement, result: MutableList + ): KotlinJvmBinaryClass.AnnotationArgumentVisitor { + return object : AnnotationMemberDefaultValueVisitor() { override fun visitEnd() { - if (!isRepeatableWithImplicitContainer(annotationClassId, arguments)) { - result.add(annotationClassId) + if (!isRepeatableWithImplicitContainer(annotationClassId, args)) { + result.add(AnnotationWithArgs(annotationClassId, args)) } } - - override fun visit(name: Name?, value: Any?) = Unit - override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) = Unit - override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? = null - override fun visitAnnotation(name: Name?, classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor? = null } } @@ -188,12 +178,13 @@ private class AnnotationLoaderForClassFileStubBuilder( if (annotationClassId != SpecialJvmAnnotations.JAVA_LANG_ANNOTATION_REPEATABLE) return false val containerKClassValue = arguments[JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME] as? KClassValue ?: return false - val normalClass = containerKClassValue.value as? KClassValue.Value.NormalClass ?: return false - return isImplicitRepeatableContainer(normalClass.classId) + return isImplicitRepeatableContainer((containerKClassValue.value as KClassValue.Value.NormalClass).classId) } - private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): AnnotationsClassIdContainer { - val memberAnnotations = HashMap>() + private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): AnnotationsContainerWithConstants> { + val memberAnnotations = HashMap>() + val propertyConstants = HashMap>() + val annotationParametersDefaultValues = HashMap>() kotlinClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor { override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor { @@ -226,7 +217,7 @@ private class AnnotationLoaderForClassFileStubBuilder( } open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor { - private val result = ArrayList() + private val result = ArrayList() override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { return loadAnnotationIfNotSpecial(classId, source, result) @@ -240,10 +231,10 @@ private class AnnotationLoaderForClassFileStubBuilder( } }, getCachedFileContent(kotlinClass)) - return AnnotationsClassIdContainer(memberAnnotations) + return AnnotationsContainerWithConstants( + memberAnnotations, + propertyConstants, + annotationParametersDefaultValues + ) } - - class AnnotationsClassIdContainer( - override val memberAnnotations: Map> - ) : AbstractBinaryClassAnnotationLoader.AnnotationsContainer() -} +} \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotationValues/AnnotationValues.kt b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotationValues/AnnotationValues.kt new file mode 100644 index 00000000000..91075a60deb --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotationValues/AnnotationValues.kt @@ -0,0 +1,109 @@ +package test + +import test.E.E1 +import kotlin.reflect.KClass + +const val CONSTANT = 12 + +class AnnotationValues { + @Simple( + 12, + 12L, + 12, + + 3.3, + f = 3.3F, + + c = 'a', + + b1 = true, + b2 = false + ) + class WithSimple + + @StringLiteral("some", "", "H$CONSTANT") + class WithStringLiteral + + @EnumLiteral(E1, E.E2, e3 = test.E.E2) + class WithEnumLiteral + + @VarArg(1, 2, 3) + class WithVarArg + + @Arrays( + [1, 2, 3], + [1L], + [], + [2.2], + ['a'], + [true, false] + ) + class WithArrays + + @ClassLiteral( + WithClassLiteral::class, + String::class + ) + class WithClassLiteral + + @Outer("value", nested = Nested(12, "nested value")) + class WithNested +} + +annotation class Simple( + val i: Int, + val l: Long, + val b: Byte, + + val d: Double, + val f: Float, + + val c: Char, + + val b1: Boolean, + val b2: Boolean +) + +annotation class StringLiteral( + val s1: String, + val s2: String, + val s3: String +) + +enum class E { + E1, E2 +} +annotation class EnumLiteral( + val e1: E, + val e2: E, + val e3: E +) + +annotation class VarArg( + vararg val v: Int +) + +annotation class Arrays( + val ia: IntArray, + val la: LongArray, + val fa: FloatArray, + val da: DoubleArray, + val ca: CharArray, + val ba: BooleanArray +) + +annotation class ClassLiteral( + val c1: KClass<*>, + val c2: KClass<*> +) + + +annotation class Nested( + val i: Int, + val s: String +) + +annotation class Outer( + val some: String, + val nested: Nested +) diff --git a/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotationValues/AnnotationValues.txt b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotationValues/AnnotationValues.txt new file mode 100644 index 00000000000..47d5d81a944 --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotationValues/AnnotationValues.txt @@ -0,0 +1,110 @@ +PsiJetFileStubImpl[package=test] +KotlinStub$PACKAGE_DIRECTIVE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] +KotlinStub$IMPORT_LIST +KotlinStub$CLASS[classId=test/AnnotationValues, fqName=test.AnnotationValues, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=true, name=AnnotationValues, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=AnnotationValues] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$CLASS[classId=test/AnnotationValues.WithArrays, fqName=test.AnnotationValues.WithArrays, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=WithArrays, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$ANNOTATION_ENTRY[hasValueArguments=false, shortName=Arrays] + valueArguments: (ia = [1, 2, 3], la = [1.toLong()], fa = [], da = [2.2.toDouble()], ca = [\u0061 ('a')], ba = [true, false]) + KotlinStub$CONSTRUCTOR_CALLEE + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] + KotlinStub$REFERENCE_EXPRESSION[referencedName=Arrays] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=WithArrays] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$CLASS[classId=test/AnnotationValues.WithClassLiteral, fqName=test.AnnotationValues.WithClassLiteral, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=WithClassLiteral, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$ANNOTATION_ENTRY[hasValueArguments=false, shortName=ClassLiteral] + valueArguments: (c1 = NormalClass(value=test/AnnotationValues.WithClassLiteral), c2 = NormalClass(value=kotlin/String)) + KotlinStub$CONSTRUCTOR_CALLEE + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] + KotlinStub$REFERENCE_EXPRESSION[referencedName=ClassLiteral] + KotlinStub$TYPE_PARAMETER_LIST + KotlinStub$TYPE_PARAMETER[fqName=null, isInVariance=false, isOutVariance=false, name=T] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=WithClassLiteral] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$CLASS[classId=test/AnnotationValues.WithEnumLiteral, fqName=test.AnnotationValues.WithEnumLiteral, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=WithEnumLiteral, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$ANNOTATION_ENTRY[hasValueArguments=false, shortName=EnumLiteral] + valueArguments: (e1 = E.E1, e2 = E.E2, e3 = E.E2) + KotlinStub$CONSTRUCTOR_CALLEE + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] + KotlinStub$REFERENCE_EXPRESSION[referencedName=EnumLiteral] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=WithEnumLiteral] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$CLASS[classId=test/AnnotationValues.WithNested, fqName=test.AnnotationValues.WithNested, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=WithNested, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$ANNOTATION_ENTRY[hasValueArguments=false, shortName=Outer] + valueArguments: (some = "value", nested = Value(type=KotlinClassTypeBean(classId=test/Nested, arguments=[], nullable=false), argumentsMapping={i=12, s="nested value"})) + KotlinStub$CONSTRUCTOR_CALLEE + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] + KotlinStub$REFERENCE_EXPRESSION[referencedName=Outer] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=WithNested] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$CLASS[classId=test/AnnotationValues.WithSimple, fqName=test.AnnotationValues.WithSimple, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=WithSimple, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$ANNOTATION_ENTRY[hasValueArguments=false, shortName=Simple] + valueArguments: (i = 12, l = 12.toLong(), b = 12.toByte(), d = 3.3.toDouble(), f = 3.3.toFloat(), c = \u0061 ('a'), b1 = true, b2 = false) + KotlinStub$CONSTRUCTOR_CALLEE + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] + KotlinStub$REFERENCE_EXPRESSION[referencedName=Simple] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=WithSimple] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$CLASS[classId=test/AnnotationValues.WithStringLiteral, fqName=test.AnnotationValues.WithStringLiteral, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=WithStringLiteral, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$ANNOTATION_ENTRY[hasValueArguments=false, shortName=StringLiteral] + valueArguments: (s1 = "some", s2 = "", s3 = "H12") + KotlinStub$CONSTRUCTOR_CALLEE + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] + KotlinStub$REFERENCE_EXPRESSION[referencedName=StringLiteral] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=WithStringLiteral] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY + KotlinStub$CLASS[classId=test/AnnotationValues.WithVarArg, fqName=test.AnnotationValues.WithVarArg, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=WithVarArg, superNames=[]] + KotlinStub$MODIFIER_LIST[public final] + KotlinStub$ANNOTATION_ENTRY[hasValueArguments=false, shortName=VarArg] + valueArguments: (v = [1, 2, 3]) + KotlinStub$CONSTRUCTOR_CALLEE + KotlinStub$TYPE_REFERENCE + KotlinStub$USER_TYPE + KotlinStub$USER_TYPE + KotlinStub$REFERENCE_EXPRESSION[referencedName=test] + KotlinStub$REFERENCE_EXPRESSION[referencedName=VarArg] + KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=WithVarArg] + KotlinStub$MODIFIER_LIST[public] + KotlinStub$VALUE_PARAMETER_LIST + KotlinStub$CLASS_BODY \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt index 7d9f4dd01f2..8e4dfd0c8e5 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt @@ -50,6 +50,16 @@ abstract class AbstractAdditionalStubInfoTest : AbstractDecompiledClassTest() { builder.append("\n").append(" ".repeat(level)).append("initializer: ${initializer.value}") } } + is KotlinAnnotationEntryStubImpl -> { + val arguments = stub.valueArguments + if (arguments != null) { + builder + .append("\n") + .append(" ".repeat(level)) + .append("valueArguments: ") + .append(arguments.entries.joinToString(", ", "(", ")") { "${it.key.asString()} = ${it.value}" }) + } + } } for (child in stub.childrenStubs) { builder.append("\n").append(" ".repeat(level)) diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java index 8cd1b80f3b0..7d6442530e1 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AdditionalStubInfoTestGenerated.java @@ -30,6 +30,12 @@ public class AdditionalStubInfoTestGenerated extends AbstractAdditionalStubInfoT runTest("analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotatedFlexibleTypes/"); } + @Test + @TestMetadata("AnnotationValues") + public void testAnnotationValues() throws Exception { + runTest("analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/AnnotationValues/"); + } + @Test @TestMetadata("Contracts") public void testContracts() throws Exception { diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/AnnotationWithArgs.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/AnnotationWithArgs.kt new file mode 100644 index 00000000000..9eb0d2a5306 --- /dev/null +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/AnnotationWithArgs.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.decompiler.stub + +import org.jetbrains.kotlin.constant.ConstantValue +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name + + +data class AnnotationWithArgs(val classId: ClassId, val args: Map>) diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/CallableClsStubBuilder.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/CallableClsStubBuilder.kt index c89a3a35d85..ebbea60075c 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/CallableClsStubBuilder.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/CallableClsStubBuilder.kt @@ -114,7 +114,7 @@ abstract class CallableClsStubBuilder( } abstract val receiverType: ProtoBuf.Type? - abstract val receiverAnnotations: List + abstract val receiverAnnotations: List abstract val returnType: ProtoBuf.Type? abstract val contextReceiverTypes: List @@ -149,11 +149,11 @@ private class FunctionClsStubBuilder( override val receiverType: ProtoBuf.Type? get() = functionProto.receiverType(c.typeTable) - override val receiverAnnotations: List + override val receiverAnnotations: List get() { return c.components.annotationLoader .loadExtensionReceiverParameterAnnotations(protoContainer, functionProto, AnnotatedCallableKind.FUNCTION) - .map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) } + .map { AnnotationWithTarget(it, AnnotationUseSiteTarget.RECEIVER) } } override val returnType: ProtoBuf.Type @@ -176,10 +176,10 @@ private class FunctionClsStubBuilder( // If function is marked as having no annotations, we don't create stubs for it if (!Flags.HAS_ANNOTATIONS.get(functionProto.flags)) return - val annotationIds = c.components.annotationLoader.loadCallableAnnotations( + val annotations = c.components.annotationLoader.loadCallableAnnotations( protoContainer, functionProto, AnnotatedCallableKind.FUNCTION ) - createAnnotationStubs(annotationIds, modifierListStubImpl) + createAnnotationStubs(annotations, modifierListStubImpl) } override fun doCreateCallableStub(parent: StubElement): StubElement { @@ -217,10 +217,10 @@ private class PropertyClsStubBuilder( override val receiverType: ProtoBuf.Type? get() = propertyProto.receiverType(c.typeTable) - override val receiverAnnotations: List + override val receiverAnnotations: List get() = c.components.annotationLoader .loadExtensionReceiverParameterAnnotations(protoContainer, propertyProto, AnnotatedCallableKind.PROPERTY_GETTER) - .map { ClassIdWithTarget(it, AnnotationUseSiteTarget.RECEIVER) } + .map { AnnotationWithTarget(it, AnnotationUseSiteTarget.RECEIVER) } override val returnType: ProtoBuf.Type get() = propertyProto.returnType(c.typeTable) @@ -250,9 +250,9 @@ private class PropertyClsStubBuilder( val delegateFieldAnnotations = c.components.annotationLoader.loadPropertyDelegateFieldAnnotations(protoContainer, propertyProto) val allAnnotations = - propertyAnnotations.map { ClassIdWithTarget(it, null) } + - backingFieldAnnotations.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.FIELD) } + - delegateFieldAnnotations.map { ClassIdWithTarget(it, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD) } + propertyAnnotations.map { AnnotationWithTarget(it, null) } + + backingFieldAnnotations.map { AnnotationWithTarget(it, AnnotationUseSiteTarget.FIELD) } + + delegateFieldAnnotations.map { AnnotationWithTarget(it, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD) } createTargetedAnnotationStubs(allAnnotations, modifierListStubImpl) } @@ -360,74 +360,11 @@ private class PropertyClsStubBuilder( ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? = null override fun visitAnnotationMemberDefaultValue(): KotlinJvmBinaryClass.AnnotationArgumentVisitor { - class AnnotationMemberDefaultValueVisitor : KotlinJvmBinaryClass.AnnotationArgumentVisitor { - private val args = mutableMapOf>() - - private fun nameOrSpecial(name: Name?): Name { - return name ?: Name.special("") - } - - override fun visit(name: Name?, value: Any?) { - args[nameOrSpecial(name)] = createConstantValue(value) - } - - override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) { - args[nameOrSpecial(name)] = createConstantValue(KClassData(value.classId, value.arrayNestedness)) - } - - override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) { - args[nameOrSpecial(name)] = createConstantValue(EnumData(enumClassId, enumEntryName)) - } - - override fun visitAnnotation( - name: Name?, - classId: ClassId - ): KotlinJvmBinaryClass.AnnotationArgumentVisitor { - val visitor = AnnotationMemberDefaultValueVisitor() - return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { - override fun visitEnd() { - args[nameOrSpecial(name)] = createConstantValue(AnnotationData(classId, visitor.args)) - } - } - } - - override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor { - return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor { - private val elements = mutableListOf() - - override fun visit(value: Any?) { - elements.addIfNotNull(value) - } - - override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) { - elements.add(EnumData(enumClassId, enumEntryName)) - } - - override fun visitClassLiteral(value: ClassLiteralValue) { - elements.add(KClassData(value.classId, value.arrayNestedness)) - } - - override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor { - val visitor = AnnotationMemberDefaultValueVisitor() - return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { - override fun visitEnd() { - elements.addIfNotNull(AnnotationData(classId, visitor.args)) - } - } - } - - override fun visitEnd() { - args[nameOrSpecial(name)] = createConstantValue(elements.toTypedArray()) - } - } - } - + return object : AnnotationMemberDefaultValueVisitor() { override fun visitEnd() { constantInitializer = args.values.firstOrNull() } } - - return AnnotationMemberDefaultValueVisitor() } override fun visitAnnotation( @@ -482,7 +419,7 @@ private class ConstructorClsStubBuilder( override val receiverType: ProtoBuf.Type? get() = null - override val receiverAnnotations: List + override val receiverAnnotations: List get() = emptyList() override val returnType: ProtoBuf.Type? @@ -519,3 +456,69 @@ private class ConstructorClsStubBuilder( KotlinConstructorStubImpl(parent, KtStubElementTypes.PRIMARY_CONSTRUCTOR, name, hasBody = false, isDelegatedCallToThis = false) } } + +open class AnnotationMemberDefaultValueVisitor : KotlinJvmBinaryClass.AnnotationArgumentVisitor { + protected val args = mutableMapOf>() + + private fun nameOrSpecial(name: Name?): Name { + return name ?: Name.special("") + } + + override fun visit(name: Name?, value: Any?) { + val constantValue = createConstantValue(value) + args[nameOrSpecial(name)] = constantValue + } + + override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) { + args[nameOrSpecial(name)] = createConstantValue(KClassData(value.classId, value.arrayNestedness)) + } + + override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) { + args[nameOrSpecial(name)] = createConstantValue(EnumData(enumClassId, enumEntryName)) + } + + override fun visitAnnotation( + name: Name?, + classId: ClassId + ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { + val visitor = AnnotationMemberDefaultValueVisitor() + return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { + override fun visitEnd() { + args[nameOrSpecial(name)] = createConstantValue(AnnotationData(classId, visitor.args)) + } + } + } + + override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor? { + return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor { + private val elements = mutableListOf() + + override fun visit(value: Any?) { + elements.addIfNotNull(value) + } + + override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) { + elements.add(EnumData(enumClassId, enumEntryName)) + } + + override fun visitClassLiteral(value: ClassLiteralValue) { + elements.add(KClassData(value.classId, value.arrayNestedness)) + } + + override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor { + val visitor = AnnotationMemberDefaultValueVisitor() + return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor { + override fun visitEnd() { + elements.addIfNotNull(AnnotationData(classId, visitor.args)) + } + } + } + + override fun visitEnd() { + args[nameOrSpecial(name)] = createConstantValue(elements.toTypedArray()) + } + } + } + + override fun visitEnd() {} +} \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/ClsStubBuilderContext.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/ClsStubBuilderContext.kt index 4586929bc32..055aa396395 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/ClsStubBuilderContext.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/ClsStubBuilderContext.kt @@ -18,11 +18,11 @@ import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer import org.jetbrains.kotlin.serialization.deserialization.getName -data class ClassIdWithTarget(val classId: ClassId, val target: AnnotationUseSiteTarget?) +data class AnnotationWithTarget(val annotationWithArgs: AnnotationWithArgs, val target: AnnotationUseSiteTarget?) class ClsStubBuilderComponents( val classDataFinder: ClassDataFinder, - val annotationLoader: AnnotationLoader, + val annotationLoader: AnnotationLoader, val virtualFileForDebug: VirtualFile, val serializationProtocol: SerializerExtensionProtocol, val classFinder: KotlinClassFinder? = null, diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt index f6b509fec31..f20a5357a09 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/TypeClsStubBuilder.kt @@ -37,7 +37,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { fun createTypeReferenceStub( parent: StubElement, type: Type, - additionalAnnotations: () -> List = { emptyList() } + additionalAnnotations: () -> List = { emptyList() } ) { val abbreviatedType = type.abbreviatedType(c.typeTable) if (abbreviatedType != null) { @@ -47,11 +47,11 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { val typeReference = KotlinPlaceHolderStubImpl(parent, KtStubElementTypes.TYPE_REFERENCE) val annotations = c.components.annotationLoader.loadTypeAnnotations(type, c.nameResolver).filterNot { - val isTopLevelClass = !it.isNestedClass - isTopLevelClass && it.asSingleFqName() in ANNOTATIONS_NOT_LOADED_FOR_TYPES + val isTopLevelClass = !it.classId.isNestedClass + isTopLevelClass && it.classId.asSingleFqName() in ANNOTATIONS_NOT_LOADED_FOR_TYPES } - val allAnnotations = additionalAnnotations() + annotations.map { ClassIdWithTarget(it, null) } + val allAnnotations = additionalAnnotations() + annotations.map { AnnotationWithTarget(it, null) } when { type.hasClassName() || type.hasTypeAliasName() -> @@ -71,7 +71,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { else parent - private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List) { + private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List) { createTypeAnnotationStubs(parent, type, annotations) val upperBoundType = if (type.hasFlexibleTypeCapabilitiesId()) { createKotlinTypeBean(type.flexibleUpperBound(c.typeTable)!!) @@ -95,7 +95,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { KotlinNameReferenceExpressionStubImpl(userType, StandardNames.FqNames.any.shortName().ref()) } - private fun createClassReferenceTypeStub(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List) { + private fun createClassReferenceTypeStub(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List) { if (type.hasFlexibleTypeCapabilitiesId()) { val id = c.nameResolver.getString(type.flexibleTypeCapabilitiesId) @@ -113,11 +113,11 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { val shouldBuildAsFunctionType = isBuiltinFunctionClass(classId) && type.argumentList.none { it.projection == Projection.STAR } if (shouldBuildAsFunctionType) { val (extensionAnnotations, notExtensionAnnotations) = annotations.partition { - it.classId.asSingleFqName() == StandardNames.FqNames.extensionFunctionType + it.annotationWithArgs.classId.asSingleFqName() == StandardNames.FqNames.extensionFunctionType } val (contextReceiverAnnotations, otherAnnotations) = notExtensionAnnotations.partition { - it.classId.asSingleFqName() == StandardNames.FqNames.contextFunctionTypeParams + it.annotationWithArgs.classId.asSingleFqName() == StandardNames.FqNames.contextFunctionTypeParams } val isExtension = extensionAnnotations.isNotEmpty() @@ -194,7 +194,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) { } else lowerBound } - private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List) { + private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List) { val typeModifiers = getTypeModifiersAsWritten(type) if (annotations.isEmpty() && typeModifiers.isEmpty()) return val typeModifiersMask = ModifierMaskUtils.computeMask { it in typeModifiers } diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt index 0fb5d59c045..df7522253b5 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/clsStubBuilding.kt @@ -192,22 +192,23 @@ fun createEmptyModifierListStub(parent: KotlinStubBaseImpl<*>): KotlinModifierLi ) } -fun createAnnotationStubs(annotationIds: List, parent: KotlinStubBaseImpl<*>) { - return createTargetedAnnotationStubs(annotationIds.map { ClassIdWithTarget(it, null) }, parent) +fun createAnnotationStubs(annotations: List, parent: KotlinStubBaseImpl<*>) { + return createTargetedAnnotationStubs(annotations.map { AnnotationWithTarget(it, null) }, parent) } fun createTargetedAnnotationStubs( - annotationIds: List, + annotations: List, parent: KotlinStubBaseImpl<*> ) { - if (annotationIds.isEmpty()) return + if (annotations.isEmpty()) return - annotationIds.forEach { annotation -> - val (annotationClassId, target) = annotation + annotations.forEach { annotation -> + val (annotationWithArgs, target) = annotation val annotationEntryStubImpl = KotlinAnnotationEntryStubImpl( parent, - shortName = annotationClassId.shortClassName.ref(), - hasValueArguments = false + shortName = annotationWithArgs.classId.shortClassName.ref(), + hasValueArguments = false, + annotationWithArgs.args ) if (target != null) { KotlinAnnotationUseSiteTargetStubImpl(annotationEntryStubImpl, StringRef.fromString(target.name)!!) @@ -215,7 +216,7 @@ fun createTargetedAnnotationStubs( val constructorCallee = KotlinPlaceHolderStubImpl(annotationEntryStubImpl, KtStubElementTypes.CONSTRUCTOR_CALLEE) val typeReference = KotlinPlaceHolderStubImpl(constructorCallee, KtStubElementTypes.TYPE_REFERENCE) - createStubForTypeName(annotationClassId, typeReference) + createStubForTypeName(annotationWithArgs.classId, typeReference) } } diff --git a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/typeAliasClsStubBuilding.kt b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/typeAliasClsStubBuilding.kt index 84ee3bfdec2..4b026d7fecc 100644 --- a/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/typeAliasClsStubBuilding.kt +++ b/analysis/decompiled/decompiler-to-stubs/src/org/jetbrains/kotlin/analysis/decompiler/stub/typeAliasClsStubBuilding.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.metadata.deserialization.underlyingType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.psi.stubs.impl.KotlinTypeAliasStubImpl import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer -import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getName fun createTypeAliasStub( @@ -42,7 +41,12 @@ fun createTypeAliasStub( } if (Flags.HAS_ANNOTATIONS.get(typeAliasProto.flags)) { - createAnnotationStubs(typeAliasProto.annotationList.map { c.nameResolver.getClassId(it.id) }, modifierList) + createAnnotationStubs( + typeAliasProto.annotationList.map { + c.components.annotationLoader.loadAnnotation(it, c.nameResolver) + }, + modifierList + ) } val typeAliasUnderlyingType = typeAliasProto.underlyingType(c.typeTable) diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtAnnotationEntryElementType.java b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtAnnotationEntryElementType.java index 8fa13106de8..9af2d23f98a 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtAnnotationEntryElementType.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/elements/KtAnnotationEntryElementType.java @@ -23,13 +23,18 @@ import com.intellij.psi.stubs.StubOutputStream; import com.intellij.util.io.StringRef; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.constant.ConstantValue; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.KtAnnotationEntry; import org.jetbrains.kotlin.psi.KtValueArgumentList; import org.jetbrains.kotlin.psi.stubs.KotlinAnnotationEntryStub; import org.jetbrains.kotlin.psi.stubs.impl.KotlinAnnotationEntryStubImpl; +import org.jetbrains.kotlin.psi.stubs.impl.KotlinConstantValueKt; import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; public class KtAnnotationEntryElementType extends KtStubElementType { @@ -44,13 +49,24 @@ public class KtAnnotationEntryElementType extends KtStubElementType) parentStub, StringRef.fromString(resultName), hasValueArguments); + return new KotlinAnnotationEntryStubImpl((StubElement) parentStub, StringRef.fromString(resultName), hasValueArguments, null); } @Override public void serialize(@NotNull KotlinAnnotationEntryStub stub, @NotNull StubOutputStream dataStream) throws IOException { dataStream.writeName(stub.getShortName()); dataStream.writeBoolean(stub.hasValueArguments()); + if (stub instanceof KotlinAnnotationEntryStubImpl) { + Map> arguments = ((KotlinAnnotationEntryStubImpl) stub).getValueArguments(); + dataStream.writeInt(arguments != null ? arguments.size() : 0); + if (arguments != null) { + for (Map.Entry> valueEntry : arguments.entrySet()) { + dataStream.writeName(valueEntry.getKey().asString()); + ConstantValue value = valueEntry.getValue(); + KotlinConstantValueKt.serialize(value, dataStream); + } + } + } } @NotNull @@ -58,7 +74,13 @@ public class KtAnnotationEntryElementType extends KtStubElementType) parentStub, text, hasValueArguments); + int valueArgCount = dataStream.readInt(); + Map> args = new LinkedHashMap<>(); + for (int i = 0; i < valueArgCount; i++) { + args.put(Name.identifier(Objects.requireNonNull(dataStream.readNameString())), + KotlinConstantValueKt.createConstantValue(dataStream)); + } + return new KotlinAnnotationEntryStubImpl((StubElement) parentStub, text, hasValueArguments, args.isEmpty() ? null : args); } @Override diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinAnnotationEntryStubImpl.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinAnnotationEntryStubImpl.kt index 9874ff35d11..fb913f17ad2 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinAnnotationEntryStubImpl.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinAnnotationEntryStubImpl.kt @@ -22,11 +22,14 @@ import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.stubs.KotlinAnnotationEntryStub import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.constant.ConstantValue +import org.jetbrains.kotlin.name.Name class KotlinAnnotationEntryStubImpl( parent: StubElement?, private val shortName: StringRef?, - private val hasValueArguments: Boolean + private val hasValueArguments: Boolean, + val valueArguments: Map>? ) : KotlinStubBaseImpl(parent, KtStubElementTypes.ANNOTATION_ENTRY), KotlinAnnotationEntryStub { override fun getShortName() = shortName?.string diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt index b1d7a91b4fb..fedbf3574a7 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.load.kotlin import org.jetbrains.kotlin.SpecialJvmAnnotations import org.jetbrains.kotlin.builtins.UnsignedTypes import org.jetbrains.kotlin.descriptors.SourceElement -import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader.AnnotationsContainerWithConstants import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.Flags import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil @@ -161,11 +160,5 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader( val normalClass = containerKClassValue.value as? KClassValue.Value.NormalClass ?: return false return isImplicitRepeatableContainer(normalClass.classId) } - - class AnnotationsContainerWithConstants( - override val memberAnnotations: Map>, - val propertyConstants: Map, - val annotationParametersDefaultValues: Map - ) : AbstractBinaryClassAnnotationLoader.AnnotationsContainer() } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt index 7cea5104f2c..999444b1981 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/BinaryClassAnnotationAndConstantLoaderImpl.kt @@ -36,7 +36,7 @@ class BinaryClassAnnotationAndConstantLoaderImpl( override var jvmMetadataVersion: JvmMetadataVersion = JvmMetadataVersion.INSTANCE - override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor = + override fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor = annotationDeserializer.deserializeAnnotation(proto, nameResolver) override fun loadConstant(desc: String, initializer: Any): ConstantValue<*>? { diff --git a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationLoader.kt b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationLoader.kt index 936e5f0d099..5d21f9d47ac 100644 --- a/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationLoader.kt +++ b/core/deserialization.common.jvm/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationLoader.kt @@ -36,7 +36,7 @@ abstract class AbstractBinaryClassAnnotationLoader ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? - protected abstract fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): A + abstract override fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): A protected fun loadAnnotationIfNotSpecial( annotationClassId: ClassId, @@ -194,11 +194,11 @@ abstract class AbstractBinaryClassAnnotationLoader { - return proto.getExtension(JvmProtoBuf.typeAnnotation).map { loadTypeAnnotation(it, nameResolver) } + return proto.getExtension(JvmProtoBuf.typeAnnotation).map { loadAnnotation(it, nameResolver) } } override fun loadTypeParameterAnnotations(proto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List { - return proto.getExtension(JvmProtoBuf.typeParameterAnnotation).map { loadTypeAnnotation(it, nameResolver) } + return proto.getExtension(JvmProtoBuf.typeParameterAnnotation).map { loadAnnotation(it, nameResolver) } } protected fun findClassWithAnnotationsAndInitializers( @@ -309,6 +309,12 @@ abstract class AbstractBinaryClassAnnotationLoader( + override val memberAnnotations: Map>, + val propertyConstants: Map, + val annotationParametersDefaultValues: Map +) : AbstractBinaryClassAnnotationLoader.AnnotationsContainer() + fun getPropertySignature( proto: ProtoBuf.Property, nameResolver: NameResolver, diff --git a/core/deserialization.common/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationLoader.kt b/core/deserialization.common/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationLoader.kt index 377f3657733..b410046a997 100644 --- a/core/deserialization.common/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationLoader.kt +++ b/core/deserialization.common/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationLoader.kt @@ -60,4 +60,6 @@ interface AnnotationLoader { proto: ProtoBuf.TypeParameter, nameResolver: NameResolver ): List + + fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): A } \ No newline at end of file diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt index 9e4ea6839e1..d1733cf7ffc 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/AnnotationAndConstantLoaderImpl.kt @@ -39,6 +39,10 @@ class AnnotationAndConstantLoaderImpl( return annotations.map { proto -> deserializer.deserializeAnnotation(proto, container.nameResolver) } } + override fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor { + return deserializer.deserializeAnnotation(proto, nameResolver) + } + override fun loadCallableAnnotations( container: ProtoContainer, proto: MessageLite,