[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:
+24
-17
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+31
-40
@@ -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>()
|
||||
}
|
||||
}
|
||||
+109
@@ -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
|
||||
)
|
||||
+110
@@ -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
|
||||
+10
@@ -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))
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+13
@@ -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<*>>)
|
||||
+78
-75
@@ -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() {}
|
||||
}
|
||||
+2
-2
@@ -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,
|
||||
|
||||
+9
-9
@@ -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 }
|
||||
|
||||
+10
-9
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -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)
|
||||
|
||||
+24
-2
@@ -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
|
||||
|
||||
+4
-1
@@ -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
|
||||
|
||||
-7
@@ -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>()
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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<*>? {
|
||||
|
||||
+9
-3
@@ -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,
|
||||
|
||||
+2
@@ -60,4 +60,6 @@ interface AnnotationLoader<out A : Any> {
|
||||
proto: ProtoBuf.TypeParameter,
|
||||
nameResolver: NameResolver
|
||||
): List<A>
|
||||
|
||||
fun loadAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): A
|
||||
}
|
||||
+4
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user