[cls] include annotation arguments in cls stubs

^ KTIJ-24666
this would allow to build fir based on stubs,
do not keep ProtoBuf in memory and
search in decompiled code by stubs
This commit is contained in:
Anna Kozlova
2023-04-13 12:15:23 +02:00
parent f0af7c4228
commit 7ee648a4f5
19 changed files with 452 additions and 168 deletions
@@ -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<ClassId> {
) : AnnotationLoader<AnnotationWithArgs> {
override fun loadClassAnnotations(container: ProtoContainer.Class): List<ClassId> =
container.classProto.getExtension(protocol.classAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
override fun loadClassAnnotations(container: ProtoContainer.Class): List<AnnotationWithArgs> =
container.classProto.getExtension(protocol.classAnnotation).orEmpty()
.map { loadAnnotation(it, container.nameResolver) }
override fun loadCallableAnnotations(
container: ProtoContainer,
proto: MessageLite,
kind: AnnotatedCallableKind
): List<ClassId> {
): List<AnnotationWithArgs> {
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<ClassId> =
override fun loadPropertyBackingFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<AnnotationWithArgs> =
emptyList()
override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<ClassId> =
override fun loadPropertyDelegateFieldAnnotations(container: ProtoContainer, proto: ProtoBuf.Property): List<AnnotationWithArgs> =
emptyList()
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<ClassId> =
proto.getExtension(protocol.enumEntryAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
override fun loadEnumEntryAnnotations(container: ProtoContainer, proto: ProtoBuf.EnumEntry): List<AnnotationWithArgs> =
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<ClassId> =
proto.getExtension(protocol.parameterAnnotation).orEmpty().map { container.nameResolver.getClassId(it.id) }
): List<AnnotationWithArgs> =
proto.getExtension(protocol.parameterAnnotation).orEmpty().map { loadAnnotation(it, container.nameResolver) }
override fun loadExtensionReceiverParameterAnnotations(
container: ProtoContainer,
proto: MessageLite,
kind: AnnotatedCallableKind
): List<ClassId> = emptyList()
): List<AnnotationWithArgs> = emptyList()
override fun loadTypeAnnotations(
proto: ProtoBuf.Type,
nameResolver: NameResolver
): List<ClassId> =
proto.getExtension(protocol.typeAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
): List<AnnotationWithArgs> =
proto.getExtension(protocol.typeAnnotation).orEmpty().map { loadAnnotation(it, nameResolver) }
override fun loadTypeParameterAnnotations(proto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List<ClassId> =
proto.getExtension(protocol.typeParameterAnnotation).orEmpty().map { nameResolver.getClassId(it.id) }
override fun loadTypeParameterAnnotations(proto: ProtoBuf.TypeParameter, nameResolver: NameResolver): List<AnnotationWithArgs> =
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)
}
}
@@ -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<ClassId, AnnotationLoaderForClassFileStubBuilder.AnnotationsClassIdContainer>(kotlinClassFinder) {
) : AbstractBinaryClassAnnotationLoader<AnnotationWithArgs, AnnotationsContainerWithConstants<AnnotationWithArgs, ConstantValue<*>>>(
kotlinClassFinder
) {
private val storage =
LockBasedStorageManager.NO_LOCKS.createMemoizedFunction<KotlinJvmBinaryClass, AnnotationsClassIdContainer> { kotlinClass ->
LockBasedStorageManager.NO_LOCKS.createMemoizedFunction<KotlinJvmBinaryClass, AnnotationsContainerWithConstants<AnnotationWithArgs, ConstantValue<*>>> { kotlinClass ->
loadAnnotationsAndInitializers(kotlinClass)
}
override fun getAnnotationsContainer(binaryClass: KotlinJvmBinaryClass): AnnotationsClassIdContainer {
override fun getAnnotationsContainer(binaryClass: KotlinJvmBinaryClass): AnnotationsContainerWithConstants<AnnotationWithArgs, ConstantValue<*>> {
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<ClassId>
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
if (annotationClassId != SpecialJvmAnnotations.JAVA_LANG_ANNOTATION_REPEATABLE) {
result += annotationClassId
return null
}
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
private val arguments = mutableMapOf<Name, ConstantValue<*>>()
override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) {
if (name != null)
arguments[name] = KClassValue(value)
}
annotationClassId: ClassId, source: SourceElement, result: MutableList<AnnotationWithArgs>
): 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<MemberSignature, MutableList<ClassId>>()
private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): AnnotationsContainerWithConstants<AnnotationWithArgs, ConstantValue<*>> {
val memberAnnotations = HashMap<MemberSignature, MutableList<AnnotationWithArgs>>()
val propertyConstants = HashMap<MemberSignature, ConstantValue<*>>()
val annotationParametersDefaultValues = HashMap<MemberSignature, ConstantValue<*>>()
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<ClassId>()
private val result = ArrayList<AnnotationWithArgs>()
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<MemberSignature, List<ClassId>>
) : AbstractBinaryClassAnnotationLoader.AnnotationsContainer<ClassId>()
}
}
@@ -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<T>
@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
)
@@ -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
@@ -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))
@@ -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 {
@@ -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<Name, ConstantValue<*>>)
@@ -114,7 +114,7 @@ abstract class CallableClsStubBuilder(
}
abstract val receiverType: ProtoBuf.Type?
abstract val receiverAnnotations: List<ClassIdWithTarget>
abstract val receiverAnnotations: List<AnnotationWithTarget>
abstract val returnType: ProtoBuf.Type?
abstract val contextReceiverTypes: List<ProtoBuf.Type>
@@ -149,11 +149,11 @@ private class FunctionClsStubBuilder(
override val receiverType: ProtoBuf.Type?
get() = functionProto.receiverType(c.typeTable)
override val receiverAnnotations: List<ClassIdWithTarget>
override val receiverAnnotations: List<AnnotationWithTarget>
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<out PsiElement>): StubElement<out PsiElement> {
@@ -217,10 +217,10 @@ private class PropertyClsStubBuilder(
override val receiverType: ProtoBuf.Type?
get() = propertyProto.receiverType(c.typeTable)
override val receiverAnnotations: List<ClassIdWithTarget>
override val receiverAnnotations: List<AnnotationWithTarget>
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<Name, ConstantValue<*>>()
private fun nameOrSpecial(name: Name?): Name {
return name ?: Name.special("<no_name>")
}
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<Any>()
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<ClassIdWithTarget>
override val receiverAnnotations: List<AnnotationWithTarget>
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<Name, ConstantValue<*>>()
private fun nameOrSpecial(name: Name?): Name {
return name ?: Name.special("<no_name>")
}
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<Any>()
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() {}
}
@@ -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<ClassId>,
val annotationLoader: AnnotationLoader<AnnotationWithArgs>,
val virtualFileForDebug: VirtualFile,
val serializationProtocol: SerializerExtensionProtocol,
val classFinder: KotlinClassFinder? = null,
@@ -37,7 +37,7 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
fun createTypeReferenceStub(
parent: StubElement<out PsiElement>,
type: Type,
additionalAnnotations: () -> List<ClassIdWithTarget> = { emptyList() }
additionalAnnotations: () -> List<AnnotationWithTarget> = { emptyList() }
) {
val abbreviatedType = type.abbreviatedType(c.typeTable)
if (abbreviatedType != null) {
@@ -47,11 +47,11 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(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<ClassIdWithTarget>) {
private fun createTypeParameterStub(parent: KotlinStubBaseImpl<*>, type: Type, name: Name, annotations: List<AnnotationWithTarget>) {
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<ClassIdWithTarget>) {
private fun createClassReferenceTypeStub(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<AnnotationWithTarget>) {
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<ClassIdWithTarget>) {
private fun createTypeAnnotationStubs(parent: KotlinStubBaseImpl<*>, type: Type, annotations: List<AnnotationWithTarget>) {
val typeModifiers = getTypeModifiersAsWritten(type)
if (annotations.isEmpty() && typeModifiers.isEmpty()) return
val typeModifiersMask = ModifierMaskUtils.computeMask { it in typeModifiers }
@@ -192,22 +192,23 @@ fun createEmptyModifierListStub(parent: KotlinStubBaseImpl<*>): KotlinModifierLi
)
}
fun createAnnotationStubs(annotationIds: List<ClassId>, parent: KotlinStubBaseImpl<*>) {
return createTargetedAnnotationStubs(annotationIds.map { ClassIdWithTarget(it, null) }, parent)
fun createAnnotationStubs(annotations: List<AnnotationWithArgs>, parent: KotlinStubBaseImpl<*>) {
return createTargetedAnnotationStubs(annotations.map { AnnotationWithTarget(it, null) }, parent)
}
fun createTargetedAnnotationStubs(
annotationIds: List<ClassIdWithTarget>,
annotations: List<AnnotationWithTarget>,
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<KtConstructorCalleeExpression>(annotationEntryStubImpl, KtStubElementTypes.CONSTRUCTOR_CALLEE)
val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(constructorCallee, KtStubElementTypes.TYPE_REFERENCE)
createStubForTypeName(annotationClassId, typeReference)
createStubForTypeName(annotationWithArgs.classId, typeReference)
}
}
@@ -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)
@@ -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<KotlinAnnotationEntryStub, KtAnnotationEntry> {
@@ -44,13 +49,24 @@ public class KtAnnotationEntryElementType extends KtStubElementType<KotlinAnnota
String resultName = shortName != null ? shortName.asString() : null;
KtValueArgumentList valueArgumentList = psi.getValueArgumentList();
boolean hasValueArguments = valueArgumentList != null && !valueArgumentList.getArguments().isEmpty();
return new KotlinAnnotationEntryStubImpl((StubElement<?>) 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<Name, ConstantValue<?>> arguments = ((KotlinAnnotationEntryStubImpl) stub).getValueArguments();
dataStream.writeInt(arguments != null ? arguments.size() : 0);
if (arguments != null) {
for (Map.Entry<Name, ConstantValue<?>> 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<KotlinAnnota
public KotlinAnnotationEntryStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
StringRef text = dataStream.readName();
boolean hasValueArguments = dataStream.readBoolean();
return new KotlinAnnotationEntryStubImpl((StubElement<?>) parentStub, text, hasValueArguments);
int valueArgCount = dataStream.readInt();
Map<Name, ConstantValue<?>> 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
@@ -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<out PsiElement>?,
private val shortName: StringRef?,
private val hasValueArguments: Boolean
private val hasValueArguments: Boolean,
val valueArguments: Map<Name, ConstantValue<*>>?
) : KotlinStubBaseImpl<KtAnnotationEntry>(parent, KtStubElementTypes.ANNOTATION_ENTRY), KotlinAnnotationEntryStub {
override fun getShortName() = shortName?.string
@@ -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<A : Any, C : Any>(
val normalClass = containerKClassValue.value as? KClassValue.Value.NormalClass ?: return false
return isImplicitRepeatableContainer(normalClass.classId)
}
class AnnotationsContainerWithConstants<out A, out C>(
override val memberAnnotations: Map<MemberSignature, List<A>>,
val propertyConstants: Map<MemberSignature, C>,
val annotationParametersDefaultValues: Map<MemberSignature, C>
) : AbstractBinaryClassAnnotationLoader.AnnotationsContainer<A>()
}
@@ -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<*>? {
@@ -36,7 +36,7 @@ abstract class AbstractBinaryClassAnnotationLoader<A : Any, S : AbstractBinaryCl
result: MutableList<A>
): 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<A : Any, S : AbstractBinaryCl
}
override fun loadTypeAnnotations(proto: ProtoBuf.Type, nameResolver: NameResolver): List<A> {
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<A> {
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<A : Any, S : AbstractBinaryCl
}
}
class AnnotationsContainerWithConstants<out A, out C>(
override val memberAnnotations: Map<MemberSignature, List<A>>,
val propertyConstants: Map<MemberSignature, C>,
val annotationParametersDefaultValues: Map<MemberSignature, C>
) : AbstractBinaryClassAnnotationLoader.AnnotationsContainer<A>()
fun getPropertySignature(
proto: ProtoBuf.Property,
nameResolver: NameResolver,
@@ -60,4 +60,6 @@ interface AnnotationLoader<out A : Any> {
proto: ProtoBuf.TypeParameter,
nameResolver: NameResolver
): List<A>
fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): A
}
@@ -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,