diff options
author | Paul Phillips <paulp@improving.org> | 2011-02-14 00:21:12 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-02-14 00:21:12 +0000 |
commit | c7f0ca2897836271030cf3be0fa3c6892ea89969 (patch) | |
tree | a73398f4044b9939a8dcd43a90a48720eb005fe2 | |
parent | 4ddfe877b26a8a5dea6b71b50481cdfe88cf72c3 (diff) | |
download | scala-c7f0ca2897836271030cf3be0fa3c6892ea89969.tar.gz scala-c7f0ca2897836271030cf3be0fa3c6892ea89969.tar.bz2 scala-c7f0ca2897836271030cf3be0fa3c6892ea89969.zip |
Added new setting -Ygen-javap, which takes a di...
Added new setting -Ygen-javap, which takes a directory as an argument
and generates javap output for every generated classfile. There is still
a lot of noise in a diff: still todo is postprocessing the output to
remove diff-noise-generating numbers and such. No review.
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 24 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/Path.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/util/Javap.scala | 5 | ||||
-rw-r--r-- | src/partest/scala/tools/partest/nest/Worker.scala | 1 | ||||
-rw-r--r-- | test/files/presentation/simple-tests.check | 3 |
6 files changed, 31 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index ecfdfd9bb0..c97fdbf58e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -13,7 +13,8 @@ import scala.collection.{ mutable, immutable } import mutable.{ ListBuffer, LinkedHashSet } import scala.reflect.generic.{ PickleFormat, PickleBuffer } import scala.tools.reflect.SigParser -import scala.tools.nsc.io.AbstractFile +import scala.tools.nsc.io.{ AbstractFile, Path } +import scala.tools.nsc.util.ScalaClassLoader import scala.tools.nsc.symtab._ import scala.tools.nsc.symtab.classfile.ClassfileConstants._ @@ -47,7 +48,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { /** JVM code generation phase */ class JvmPhase(prev: Phase) extends ICodePhase(prev) { - def name = phaseName override def erasedTypes = true @@ -139,6 +139,18 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { super.javaName(sym) } + protected def emitJavap(bytes: Array[Byte], javapFile: io.File) { + import scala.tools.util.Javap + val pw = javapFile.printWriter() + try { + val javap = new Javap(ScalaClassLoader.getSystemLoader(), pw) { + override def findBytes(path: String): Array[Byte] = bytes + } + javap(Seq("-verbose", "dummy")) foreach (_.show()) + } + finally pw.close() + } + /** Write a class to disk, adding the Scala signature (pickled type * information) and inner classes. * @@ -152,6 +164,14 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { jclass writeTo outstream outstream.close() informProgress("wrote " + outfile) + + if (!settings.Ygenjavap.isDefault) { + val segments = jclass.getName().split("[./]") + val javapFile = segments.foldLeft(Path(settings.Ygenjavap.value))(_ / _) changeExtension "javap" toFile + + javapFile.parent.createDirectory() + emitJavap(outfile.toByteArray, javapFile) + } } /** Returns the ScalaSignature annotation if it must be added to this class, diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala index 314b17d35d..3e52731c62 100644 --- a/src/compiler/scala/tools/nsc/io/Path.scala +++ b/src/compiler/scala/tools/nsc/io/Path.scala @@ -198,7 +198,7 @@ class Path private[io] (val jfile: JFile) { // returns the Path with the extension. def addExtension(ext: String): Path = Path(path + "." + ext) // changes the existing extension out for a new one - def changeExtension(ext: String): Path = Path((path stripSuffix extension) + ext) + def changeExtension(ext: String): Path = Path(path stripSuffix extension) addExtension ext // conditionally execute def ifFile[T](f: File => T): Option[T] = if (isFile) Some(f(toFile)) else None diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 8151da3869..9940134b7d 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -122,6 +122,7 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { val Xshowtrees = BooleanSetting ("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs.") val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.") val skip = PhasesSetting ("-Yskip", "Skip") + val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "") val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.") val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") . withPostSetHook(set => util.Statistics.enabled = set.value) diff --git a/src/compiler/scala/tools/util/Javap.scala b/src/compiler/scala/tools/util/Javap.scala index 48971d6de0..bda8ffbd1b 100644 --- a/src/compiler/scala/tools/util/Javap.scala +++ b/src/compiler/scala/tools/util/Javap.scala @@ -20,9 +20,12 @@ class Javap( lazy val parser = new JpOptions + def findBytes(path: String): Array[Byte] = + tryFile(path) getOrElse tryClass(path) + def apply(args: Seq[String]): List[JpResult] = { args.toList filterNot (_ startsWith "-") map { path => - val bytes = tryFile(path) getOrElse tryClass(path) + val bytes = findBytes(path) if (bytes.isEmpty) new JpError("Could not find class bytes for '%s'".format(path)) else new JpSuccess(newPrinter(new ByteArrayInputStream(bytes), newEnv(args))) } diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index 6e3491cfa2..afbdfdba83 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -980,6 +980,7 @@ class Worker(val fileManager: FileManager, params: TestRunParams) extends Actor try processSingleFile(testFile) catch { case t => + succeeded = false try { val logFile = createLogFile(testFile) logStackTrace(logFile, t, "Possible compiler crash during test of: " + testFile + "\n") diff --git a/test/files/presentation/simple-tests.check b/test/files/presentation/simple-tests.check index 8cc891af4b..f3184cf457 100644 --- a/test/files/presentation/simple-tests.check +++ b/test/files/presentation/simple-tests.check @@ -134,7 +134,7 @@ askTypeCompletion at Tester.scala(27,23) ================================================================================ [response] aksTypeCompletion at (27,23) -retreived 196 members +retreived 197 members TypeMember(method !=,(x$1: AnyRef)Boolean,true,true,<none>) TypeMember(method !=,(x$1: Any)Boolean,true,true,<none>) TypeMember(method ==,(x$1: AnyRef)Boolean,true,true,<none>) @@ -194,6 +194,7 @@ TypeMember(value Ybuildmanagerdebug,Tester.this.settings.BooleanSetting,false,tr TypeMember(value Ycompacttrees,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value Ycompletion,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value YdepMethTpes,Tester.this.settings.BooleanSetting,false,true,<none>) +TypeMember(value Ygenjavap,Tester.this.settings.StringSetting,false,true,<none>) TypeMember(value Yhelp,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value Yidedebug,Tester.this.settings.BooleanSetting,false,true,<none>) TypeMember(value Ylogcp,Tester.this.settings.BooleanSetting,false,true,<none>) |