1
+ package kotlinx.benchmark.gradle
2
+
3
+ import org.jetbrains.org.objectweb.asm.*
4
+ import org.jetbrains.org.objectweb.asm.tree.*
5
+ import java.io.File
6
+
7
+ class AnnotationProcessor {
8
+
9
+ fun processClassFile (classFile : File ) {
10
+ val classReader = ClassReader (classFile.readBytes())
11
+ val classNode = ClassNode ()
12
+ classReader.accept(classNode, 0 )
13
+
14
+ classNode.visibleAnnotations?.forEach { annotationNode ->
15
+ println (" Class annotation: ${annotationNode.desc} " )
16
+ if (annotationNode.desc != " Lkotlin/Metadata;" ) {
17
+ printAnnotationValues(annotationNode)
18
+ } else {
19
+ println (" Ignoring kotlin.Metadata annotation for readability." )
20
+ }
21
+ }
22
+
23
+ classNode.methods?.forEach { methodNode ->
24
+ methodNode.visibleAnnotations?.forEach { annotationNode ->
25
+ println (" Method annotation in ${methodNode.name} : ${annotationNode.desc} " )
26
+ if (annotationNode.desc != " Lkotlin/Metadata;" ) {
27
+ printAnnotationValues(annotationNode)
28
+ } else {
29
+ println (" Ignoring kotlin.Metadata annotation for readability." )
30
+ }
31
+ }
32
+ }
33
+
34
+ classNode.fields?.forEach { fieldNode ->
35
+ fieldNode.visibleAnnotations?.forEach { annotationNode ->
36
+ println (" Field annotation in ${fieldNode.name} : ${annotationNode.desc} " )
37
+ if (annotationNode.desc != " Lkotlin/Metadata;" ) {
38
+ printAnnotationValues(annotationNode)
39
+ } else {
40
+ println (" Ignoring kotlin.Metadata annotation for readability." )
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ private fun printAnnotationValues (annotationNode : AnnotationNode ) {
47
+ annotationNode.values?.let { values ->
48
+ for (i in values.indices step 2 ) {
49
+ val name = values[i]
50
+ val value = values[i + 1 ]
51
+ println (" Annotation parameter: $name = ${formatAnnotationValue(value)} " )
52
+ }
53
+ }
54
+ }
55
+
56
+ private fun formatAnnotationValue (value : Any? ): String {
57
+ return when (value) {
58
+ is List <* > -> value.joinToString(prefix = " [" , postfix = " ]" ) { formatAnnotationValue(it) }
59
+ is Array <* > -> value.joinToString(prefix = " [" , postfix = " ]" ) { formatAnnotationValue(it) }
60
+ is TypePath -> value.toString()
61
+ is AnnotationNode -> formatAnnotationNode(value)
62
+ is Type -> value.className
63
+ is String -> " \" ${value.replace(" \" " , " \\\" " )} \" "
64
+ is ByteArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { it.toString() }
65
+ is CharArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { " \" ${it} \" " }
66
+ is ShortArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { it.toString() }
67
+ is IntArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { it.toString() }
68
+ is LongArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { it.toString() }
69
+ is FloatArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { it.toString() }
70
+ is DoubleArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { it.toString() }
71
+ is BooleanArray -> value.joinToString(prefix = " [" , postfix = " ]" ) { it.toString() }
72
+ else -> value.toString()
73
+ }
74
+ }
75
+
76
+ private fun formatAnnotationNode (annotationNode : AnnotationNode ): String {
77
+ val sb = StringBuilder (" @${annotationNode.desc} (" )
78
+ annotationNode.values?.let { values ->
79
+ for (i in values.indices step 2 ) {
80
+ val name = values[i]
81
+ val value = values[i + 1 ]
82
+ sb.append(" $name = ${formatAnnotationValue(value)} , " )
83
+ }
84
+ }
85
+ if (sb.endsWith(" , " )) {
86
+ sb.setLength(sb.length - 2 )
87
+ }
88
+ sb.append(" )" )
89
+ return sb.toString()
90
+ }
91
+ }
0 commit comments