@@ -10,15 +10,28 @@ import org.objectweb.asm.Opcodes
10
10
import org.slf4j.Logger
11
11
import org.slf4j.LoggerFactory
12
12
import java.security.MessageDigest
13
+ import java.util.Base64
14
+ import java.io.PrintWriter
15
+ import org.gradle.api.file.RegularFileProperty
16
+ import org.gradle.api.tasks.OutputFile
17
+ import org.gradle.api.tasks.Internal
18
+
19
+ interface ReaperTransformParameters : InstrumentationParameters {
20
+ @get:Internal
21
+ val instrumentationRecord: RegularFileProperty
22
+ }
23
+
24
+ var instrumentationRecordWriter: PrintWriter ? = null
13
25
14
26
abstract class ReaperClassLoadClassVisitorFactory :
15
- AsmClassVisitorFactory <InstrumentationParameters . None > {
27
+ AsmClassVisitorFactory <ReaperTransformParameters > {
16
28
companion object {
17
29
private val logger by lazy {
18
30
LoggerFactory .getLogger(ReaperClassLoadClassVisitorFactory ::class .java)
19
31
}
20
32
}
21
33
34
+
22
35
override fun createClassVisitor (
23
36
classContext : ClassContext ,
24
37
nextClassVisitor : ClassVisitor ,
@@ -27,11 +40,17 @@ abstract class ReaperClassLoadClassVisitorFactory :
27
40
" ReaperClassVisitorFactory processing class: ${classContext.currentClassData.className} " ,
28
41
)
29
42
43
+ if (instrumentationRecordWriter == null ) {
44
+ val output = parameters.get().instrumentationRecord.get().getAsFile().printWriter()
45
+ instrumentationRecordWriter = output
46
+ }
47
+
30
48
return ReaperClassLoadClassVisitor (
31
49
instrumentationContext.apiVersion.get(),
32
50
nextClassVisitor,
33
51
classContext,
34
52
logger,
53
+ instrumentationRecordWriter!! ,
35
54
)
36
55
}
37
56
@@ -59,7 +78,7 @@ class ReaperClassLoadClassVisitor(
59
78
cv : ClassVisitor ,
60
79
val classContext : ClassContext ,
61
80
val logger : Logger ,
62
- // private val writer: PrintWriter,
81
+ val writer : PrintWriter ,
63
82
) : ClassVisitor(api, cv) {
64
83
private var sourceFileName: String? = null
65
84
@@ -83,24 +102,37 @@ class ReaperClassLoadClassVisitor(
83
102
return mv?.let {
84
103
val sig = " $className .$name$descriptor "
85
104
logger.info(" Processing method: $sig " )
86
- ReaperClassLoadMethodVisitor (api, mv, className, name)
105
+ ReaperClassLoadMethodVisitor (api, mv, className, name, logger, writer )
87
106
}
88
107
}
89
108
}
90
109
110
+ fun longToBase64 (hash : Long ): String {
111
+ val buf = ByteArray (8 )
112
+ for (i in 0 .. 7 ) {
113
+ buf[i] = ((hash shr i * 8 ) and 0xFFL ).toByte()
114
+ }
115
+ val hashAsBase64 = Base64 .getEncoder().encode(buf).toString(Charsets .UTF_8 )
116
+ return hashAsBase64
117
+ }
118
+
91
119
class ReaperClassLoadMethodVisitor (
92
120
api : Int ,
93
121
methodVisitor : MethodVisitor ,
94
122
private val className : String ,
95
- // private val writer: PrintWriter,
96
123
private val name : String? ,
124
+ private val logger : Logger ,
125
+ private val writer : PrintWriter ,
97
126
) : MethodVisitor(api, methodVisitor) {
98
127
override fun visitCode () {
99
128
super .visitCode()
100
129
if (name == " <clinit>" || name == " <init>" ) {
101
130
val signature = " L" + className.replace(" ." , " /" ) + " ;"
102
131
val hashedSignature = topLong(toSha256(signature))
103
132
133
+ writer.write(" ${className} \t ${hashedSignature} \t ${longToBase64(hashedSignature)} \t ${signature} \t ${name} \n " )
134
+ writer.flush()
135
+
104
136
// Push method argument onto the stack
105
137
mv.visitLdcInsn(hashedSignature)
106
138
0 commit comments