Implement AnnotationLoaderForClassFileStubBuilder

This commit is contained in:
Ilya Kirillov
2021-12-16 12:14:06 +03:00
parent b9b0bb309d
commit dbb3ebb8df
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.KClassValue import org.jetbrains.kotlin.resolve.constants.KClassValue
import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.storage.LockBasedStorageManager
open class KotlinClsStubBuilder : ClsStubBuilder() { open class KotlinClsStubBuilder : ClsStubBuilder() {
override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + KotlinStubVersions.CLASSFILE_STUB_VERSION override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + KotlinStubVersions.CLASSFILE_STUB_VERSION
@@ -122,11 +121,15 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
} }
} }
class AnnotationLoaderForClassFileStubBuilder( private class AnnotationLoaderForClassFileStubBuilder(
kotlinClassFinder: KotlinClassFinder, kotlinClassFinder: KotlinClassFinder,
private val cachedFile: VirtualFile, private val cachedFile: VirtualFile,
private val cachedFileContent: ByteArray private val cachedFileContent: ByteArray
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit>(LockBasedStorageManager.NO_LOCKS, kotlinClassFinder) { ) : AbstractBinaryClassAnnotationLoader<ClassId, AnnotationLoaderForClassFileStubBuilder.AnnotationsClassIdContainer>(kotlinClassFinder) {
override fun getAnnotationsContainer(binaryClass: KotlinJvmBinaryClass): AnnotationsClassIdContainer {
return loadAnnotationsAndInitializers(binaryClass)
}
override fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? { override fun getCachedFileContent(kotlinClass: KotlinJvmBinaryClass): ByteArray? {
if ((kotlinClass as? VirtualFileKotlinClass)?.file == cachedFile) { if ((kotlinClass as? VirtualFileKotlinClass)?.file == cachedFile) {
@@ -137,9 +140,6 @@ class AnnotationLoaderForClassFileStubBuilder(
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = nameResolver.getClassId(proto.id) override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId = nameResolver.getClassId(proto.id)
override fun loadConstant(desc: String, initializer: Any) = null
override fun transformToUnsignedConstant(constant: Unit) = null
override fun loadAnnotation( override fun loadAnnotation(
annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId> annotationClassId: ClassId, source: SourceElement, result: MutableList<ClassId>
@@ -157,9 +157,10 @@ class AnnotationLoaderForClassFileStubBuilder(
} }
override fun visitEnd() { override fun visitEnd() {
if (!isRepeatableWithImplicitContainer(annotationClassId, arguments)) { // todo
result.add(annotationClassId) // if (!isRepeatableWithImplicitContainer(annotationClassId, arguments)) {
} // result.add(annotationClassId)
// }
} }
override fun visit(name: Name?, value: Any?) = Unit override fun visit(name: Name?, value: Any?) = Unit
@@ -169,9 +170,58 @@ class AnnotationLoaderForClassFileStubBuilder(
} }
} }
override fun loadAnnotationMethodDefaultValue( private fun loadAnnotationsAndInitializers(kotlinClass: KotlinJvmBinaryClass): AnnotationsClassIdContainer {
annotationClass: KotlinJvmBinaryClass, val memberAnnotations = HashMap<MemberSignature, MutableList<ClassId>>()
methodSignature: MemberSignature,
visitResult: (Unit) -> Unit kotlinClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? = null override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor {
return AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name.asString(), desc))
}
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor {
val signature = MemberSignature.fromFieldNameAndDesc(name.asString(), desc)
return MemberAnnotationVisitor(signature)
}
inner class AnnotationVisitorForMethod(signature: MemberSignature) : MemberAnnotationVisitor(signature),
KotlinJvmBinaryClass.MethodAnnotationVisitor {
override fun visitParameterAnnotation(
index: Int, classId: ClassId, source: SourceElement
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
val paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index)
var result = memberAnnotations[paramSignature]
if (result == null) {
result = ArrayList()
memberAnnotations[paramSignature] = result
}
return loadAnnotationIfNotSpecial(classId, source, result)
}
override fun visitAnnotationMemberDefaultValue(): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return null
}
}
open inner class MemberAnnotationVisitor(protected val signature: MemberSignature) : KotlinJvmBinaryClass.AnnotationVisitor {
private val result = ArrayList<ClassId>()
override fun visitAnnotation(classId: ClassId, source: SourceElement): KotlinJvmBinaryClass.AnnotationArgumentVisitor? {
return loadAnnotationIfNotSpecial(classId, source, result)
}
override fun visitEnd() {
if (result.isNotEmpty()) {
memberAnnotations[signature] = result
}
}
}
}, getCachedFileContent(kotlinClass))
return AnnotationsClassIdContainer(memberAnnotations)
}
class AnnotationsClassIdContainer(
override val memberAnnotations: Map<MemberSignature, List<ClassId>>
) : AbstractBinaryClassAnnotationLoader.AnnotationsContainer<ClassId>()
} }