diff options
author | Som Snytt <som.snytt@gmail.com> | 2012-11-02 22:00:03 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2012-11-28 12:52:44 -0800 |
commit | 2857d43a5a217d45f879878740081d4b91c1b2d8 (patch) | |
tree | 842862390dc664175f9e126a7ad977910a1f9816 /src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala | |
parent | 08e717eaee731456a51adb08f72aa5d9f083a29a (diff) | |
download | scala-2857d43a5a217d45f879878740081d4b91c1b2d8.tar.gz scala-2857d43a5a217d45f879878740081d4b91c1b2d8.tar.bz2 scala-2857d43a5a217d45f879878740081d4b91c1b2d8.zip |
Javap for Java 7 (Fixes SI-4936)
Add support for reflective invocation of javap under jdk7,
using the quasi-javax.tools API.
Under -Ygen-javap, warn if you can't.
Since JAVA_HOME is used to locate tools.jar, the script is
updated to convert it for cygwin.
Update Javap for simpl repl.
Also, reduce clutter of JavaxTools as suggested.
JavapTool7 evades repl truncating if enabled; the truncating PrintWriter
is not line-oriented but string-oriented.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala index 8c8950d295..941ccd9a2d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala @@ -9,7 +9,7 @@ package backend.jvm import java.io.{ DataOutputStream, FileOutputStream, OutputStream, File => JFile } import scala.tools.nsc.io._ import scala.tools.nsc.util.ScalaClassLoader -import scala.tools.util.JavapClass +import scala.tools.util.{ Javap, JavapClass } import java.util.jar.Attributes.Name import scala.language.postfixOps @@ -59,27 +59,32 @@ trait BytecodeWriters { override def close() = writer.close() } + /** To be mixed-in with the BytecodeWriter that generates + * the class file to be disassembled. + */ trait JavapBytecodeWriter extends BytecodeWriter { val baseDir = Directory(settings.Ygenjavap.value).createDirectory() - - def emitJavap(bytes: Array[Byte], javapFile: io.File) { - val pw = javapFile.printWriter() - val javap = new JavapClass(ScalaClassLoader.appLoader, pw) { - override def findBytes(path: String): Array[Byte] = bytes - } - - try javap(Seq("-verbose", "dummy")) foreach (_.show()) - finally pw.close() + val cl = ScalaClassLoader.appLoader + + def emitJavap(classFile: AbstractFile, javapFile: File) { + val pw = javapFile.printWriter() + try { + val javap = new JavapClass(cl, pw) { + override def findBytes(path: String): Array[Byte] = classFile.toByteArray + } + javap(Seq("-verbose", "-protected", classFile.name)) foreach (_.show()) + } finally pw.close() } abstract override def writeClass(label: String, jclassName: String, jclassBytes: Array[Byte], sym: Symbol) { super.writeClass(label, jclassName, jclassBytes, sym) - val bytes = getFile(sym, jclassName, ".class").toByteArray + val classFile = getFile(sym, jclassName, ".class") val segments = jclassName.split("[./]") val javapFile = segments.foldLeft(baseDir: Path)(_ / _) changeExtension "javap" toFile; - javapFile.parent.createDirectory() - emitJavap(bytes, javapFile) + + if (Javap.isAvailable(cl)) emitJavap(classFile, javapFile) + else warning("No javap on classpath, skipping javap output.") } } |