aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/shot/InjectionApplicator.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/moe/nea/shot/InjectionApplicator.kt')
-rw-r--r--src/main/kotlin/moe/nea/shot/InjectionApplicator.kt69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/main/kotlin/moe/nea/shot/InjectionApplicator.kt b/src/main/kotlin/moe/nea/shot/InjectionApplicator.kt
new file mode 100644
index 0000000..82b05a6
--- /dev/null
+++ b/src/main/kotlin/moe/nea/shot/InjectionApplicator.kt
@@ -0,0 +1,69 @@
+package moe.nea.shot
+
+import org.objectweb.asm.*
+
+class InjectionApplicator(
+ val injections: ClassShots,
+ writer: ClassWriter
+) : ClassVisitor(Opcodes.ASM9, writer) {
+
+ override fun visit(
+ version: Int,
+ access: Int,
+ name: String?,
+ signature: String?,
+ superName: String?,
+ interfaces: Array<out String>?
+ ) {
+ super.visit(version, access, name, signature, superName, interfaces)
+ for (annotation in injections.annotations) {
+ super.visitAnnotation(annotation.jvmRef, false).visitEnd()
+ }
+ }
+
+ override fun visitField(
+ access: Int,
+ name: String,
+ descriptor: String?,
+ signature: String?,
+ value: Any?
+ ): FieldVisitor {
+ val fieldVisitor = super.visitField(access, name, descriptor, signature, value)
+ val fieldShots = injections.fieldShots[FieldRef(name)] ?: return fieldVisitor
+ for (annotation in fieldShots.annotations) {
+ fieldVisitor.visitAnnotation(annotation.jvmRef, false)
+ .visitEnd()
+ }
+ return fieldVisitor
+ }
+
+ override fun visitMethod(
+ access: Int,
+ name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<out String>?
+ ): MethodVisitor {
+ val parentVisitor = super.visitMethod(access, name, descriptor, signature, exceptions)
+ val methodShots = injections.methodShots[MethodRef(name, descriptor.replaceAfter(")", ""))] ?: return parentVisitor
+ for (injection in methodShots.annotations) {
+ parentVisitor.visitAnnotation(injection.jvmRef, false)
+ .visitEnd()
+ }
+ var maxParameterCount = 0
+ for ((parameter, annotations) in methodShots.parameterAnnotations) {
+ maxParameterCount = maxOf(maxParameterCount, parameter + 1)
+ for (annotation in annotations) {
+ parentVisitor
+ .visitParameterAnnotation(parameter, annotation.jvmRef, false)
+ .visitEnd()
+ }
+ }
+ return object : MethodVisitor(Opcodes.ASM8, parentVisitor) {
+ override fun visitAnnotableParameterCount(parameterCount: Int, visible: Boolean) {
+ super.visitAnnotableParameterCount(
+ if (visible) parameterCount else maxOf(parameterCount, maxParameterCount), visible)
+ }
+ }
+ }
+} \ No newline at end of file