All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ammonite.compiler.AsmPositionUpdater.scala Maven / Gradle / Ivy

The newest version!
package ammonite.compiler

// originally based on https://github.com/VirtusLab/scala-cli/blob/67db91cfbaa74de806fd1d5ed00096affa0125c0/modules/build/src/main/scala/scala/build/postprocessing/AsmPositionUpdater.scala

import org.objectweb.asm
import java.io.InputStream

object AsmPositionUpdater {

  private class LineNumberTableMethodVisitor(
      lineShift: Int,
      delegate: asm.MethodVisitor
  ) extends asm.MethodVisitor(asm.Opcodes.ASM9, delegate) {
    override def visitLineNumber(line: Int, start: asm.Label): Unit =
      super.visitLineNumber(line + lineShift, start)
  }

  private class LineNumberTableClassVisitor(
      mappings: Map[String, (String, Int)],
      cw: asm.ClassWriter
  ) extends asm.ClassVisitor(asm.Opcodes.ASM9, cw) {
    private var lineShiftOpt = Option.empty[Int]
    def mappedStuff = lineShiftOpt.nonEmpty
    override def visitSource(source: String, debug: String): Unit =
      mappings.get(source) match {
        case None =>
          super.visitSource(source, debug)
        case Some((newSource, lineShift)) =>
          lineShiftOpt = Some(lineShift)
          super.visitSource(newSource, debug)
      }
    override def visitMethod(
        access: Int,
        name: String,
        descriptor: String,
        signature: String,
        exceptions: Array[String]
    ): asm.MethodVisitor = {
      val main = super.visitMethod(access, name, descriptor, signature, exceptions)
      lineShiftOpt match {
        case None => main
        case Some(lineShift) => new LineNumberTableMethodVisitor(lineShift, main)
      }
    }
  }

  def postProcess(
      mappings: Map[String, (String, Int)],
      clsInputStream: InputStream
  ): Option[Array[Byte]] = {
    val reader = new asm.ClassReader(clsInputStream)
    val writer = new asm.ClassWriter(reader, 0)
    val checker = new LineNumberTableClassVisitor(mappings, writer)
    reader.accept(checker, 0)
    if (checker.mappedStuff) Some(writer.toByteArray)
    else None
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy