diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/shot/InjectionApplicator.kt')
-rw-r--r-- | src/main/kotlin/moe/nea/shot/InjectionApplicator.kt | 69 |
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 |