summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-02-07 06:52:02 +0000
committerPaul Phillips <paulp@improving.org>2011-02-07 06:52:02 +0000
commit5c18620fa475d32de62472de55a6bcec3da1b515 (patch)
tree8d9363ddf785f94d610892684a5d44bf3d6986a3
parent1065c911a1b896132b54d2573d80152b5fe7404f (diff)
downloadscala-5c18620fa475d32de62472de55a6bcec3da1b515.tar.gz
scala-5c18620fa475d32de62472de55a6bcec3da1b515.tar.bz2
scala-5c18620fa475d32de62472de55a6bcec3da1b515.zip
Added all the javap command line options to :ja...
Added all the javap command line options to :javap. No review.
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala18
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/package.scala4
-rw-r--r--src/compiler/scala/tools/util/Javap.scala163
-rw-r--r--test/files/run/javap.check18
-rw-r--r--test/files/run/javap.scala24
5 files changed, 157 insertions, 70 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index b7cd227efc..f663bfd1be 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -304,17 +304,19 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
p("")
}
}
+
+ private object javap extends Javap(intp.classLoader, new IMain.ReplStrippingWriter(intp)) {
+ override def tryClass(path: String): Array[Byte] = super.tryClass(intp pathToFlatName path)
+ }
+
private def javapCommand(line: String): Result = {
if (line == "")
- return ":javap <filename or classname>"
- val javap = new Javap(intp.classLoader) {
- override def defaultPrintWriter = new IMain.ReplStrippingWriter(intp)
- }
- val path = intp.pathToFlatName(line)
- val result = javap guess path
+ return ":javap [-lcsvp] [path1 path2 ...]"
- if (result.isError) "Failed: " + result.value
- else result.show()
+ javap(words(line)) foreach { res =>
+ if (res.isError) return "Failed: " + res.value
+ else res.show()
+ }
}
private def keybindingsCommand(line: String): Result = {
if (in.keyBindings.isEmpty) "Key bindings unavailable."
diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala
index 5f231190eb..42826e9c6d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/package.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/package.scala
@@ -23,12 +23,13 @@ package scala.tools.nsc
* IMain contains { global: Global }
*/
package object interpreter {
+ type JClass = java.lang.Class[_]
+
private[nsc] val DebugProperty = "scala.repl.debug"
private[nsc] val TraceProperty = "scala.repl.trace"
private[nsc] val PowerProperty = "scala.repl.power"
private[nsc] var isReplDebug = sys.props contains DebugProperty // Also set by -Yrepl-debug
- type JClass = java.lang.Class[_]
private[nsc] implicit def enrichClass[T](clazz: Class[T]) = new RichClass[T](clazz)
/** Debug output */
@@ -42,6 +43,7 @@ package object interpreter {
x
}
+ private[nsc] def words(s: String) = s.trim split "\\s+" toList
private[nsc] def isQuoted(s: String) =
(s.length >= 2) && (s.head == s.last) && ("\"'" contains s.head)
diff --git a/src/compiler/scala/tools/util/Javap.scala b/src/compiler/scala/tools/util/Javap.scala
index b31683b1f7..48971d6de0 100644
--- a/src/compiler/scala/tools/util/Javap.scala
+++ b/src/compiler/scala/tools/util/Javap.scala
@@ -6,53 +6,55 @@
package scala.tools
package util
-import java.io.{ InputStream, PrintWriter, ByteArrayInputStream, FileNotFoundException }
import java.lang.reflect.{ GenericSignatureFormatError, Method, Constructor }
import java.lang.{ ClassLoader => JavaClassLoader }
import scala.tools.nsc.util.ScalaClassLoader
+import java.io.{ InputStream, PrintWriter, ByteArrayInputStream, FileNotFoundException }
import scala.tools.nsc.io.{ File, NullPrintStream }
+import Javap._
-trait JavapResult {
- type ResultType
- def isError: Boolean
- def value: ResultType
- def show(): Unit
- // todo
- // def header(): String
- // def fields(): List[String]
- // def methods(): List[String]
- // def signatures(): List[String]
-}
-class JavapError(msg: String) extends JavapResult {
- type ResultType = String
- def isError = true
- def value = msg
- def show() = println(msg)
-}
-class JavapSuccess(val value: AnyRef) extends JavapResult {
- type ResultType = AnyRef
- def isError = false
- def show() = value.asInstanceOf[{ def print(): Unit }].print()
-}
+class Javap(
+ val loader: ScalaClassLoader = ScalaClassLoader.getSystemLoader(),
+ val printWriter: PrintWriter = new PrintWriter(System.out, true)
+) {
+
+ lazy val parser = new JpOptions
+
+ def apply(args: Seq[String]): List[JpResult] = {
+ args.toList filterNot (_ startsWith "-") map { path =>
+ val bytes = tryFile(path) getOrElse tryClass(path)
+ if (bytes.isEmpty) new JpError("Could not find class bytes for '%s'".format(path))
+ else new JpSuccess(newPrinter(new ByteArrayInputStream(bytes), newEnv(args)))
+ }
+ }
+
+ // "documentation"
+ type FakeEnvironment = AnyRef
+ type FakePrinter = AnyRef
+
+ val Env = "sun.tools.javap.JavapEnvironment"
+ val EnvClass = loader.tryToInitializeClass[FakeEnvironment](Env).orNull
+ val EnvCtr = EnvClass.getConstructor(List[Class[_]](): _*)
-class Javap(val loader: ScalaClassLoader) {
- def this() = this(ScalaClassLoader.getSystemLoader())
- def defaultPrintWriter = new PrintWriter(System.out, true)
-
- private val envFieldsToSet = List[(String, Any)](
- // "showLineAndLocal" -> true,
- "showDisassembled" -> true,
- "showVerbose" -> true,
- "showInternalSigs" -> true
- )
- val Env = "sun.tools.javap.JavapEnvironment"
- val Printer = "sun.tools.javap.JavapPrinter"
-
- val EnvClass = loader.tryToInitializeClass[AnyRef](Env).orNull
- val PrinterClass = loader.tryToInitializeClass[AnyRef](Printer).orNull
- val EnvCtr = EnvClass.getConstructor(List[Class[_]](): _*)
+ val Printer = "sun.tools.javap.JavapPrinter"
+ val PrinterClass = loader.tryToInitializeClass[FakePrinter](Printer).orNull
val PrinterCtr = PrinterClass.getConstructor(classOf[InputStream], classOf[PrintWriter], EnvClass)
+ def newPrinter(in: InputStream, env: FakeEnvironment): FakePrinter =
+ PrinterCtr.newInstance(in, printWriter, env)
+
+ def newEnv(opts: Seq[String]): FakeEnvironment = {
+ val env: FakeEnvironment = EnvClass.newInstance()
+
+ parser(opts) foreach { case (name, value) =>
+ val field = EnvClass getDeclaredField name
+ field setAccessible true
+ field.set(env, value.asInstanceOf[AnyRef])
+ }
+
+ env
+ }
+
/** Assume the string is a path and try to find the classfile
* it represents.
*/
@@ -74,31 +76,70 @@ class Javap(val loader: ScalaClassLoader) {
)
loader.findBytesForClassName(extName)
}
+}
- def newEnv(): AnyRef = {
- val env = EnvClass.newInstance()
- envFieldsToSet foreach { case (name, value) =>
- val x = EnvClass getDeclaredField name
- x setAccessible true
- x.set(env, value.asInstanceOf[AnyRef])
- }
- env
+object Javap {
+ def apply(path: String): Unit = apply(Seq(path))
+ def apply(args: Seq[String]): Unit = new Javap() apply args foreach (_.show())
+
+ sealed trait JpResult {
+ type ResultType
+ def isError: Boolean
+ def value: ResultType
+ def show(): Unit
+ // todo
+ // def header(): String
+ // def fields(): List[String]
+ // def methods(): List[String]
+ // def signatures(): List[String]
}
- def newPrinter(
- in: InputStream,
- pw: PrintWriter = defaultPrintWriter,
- env: AnyRef = newEnv()
- ): AnyRef = {
- PrinterCtr.newInstance(in, pw, env)
+ class JpError(msg: String) extends JpResult {
+ type ResultType = String
+ def isError = true
+ def value = msg
+ def show() = println(msg)
}
-
- def guess(path: String): JavapResult = {
- val bytes = tryFile(path) getOrElse tryClass(path)
- if (bytes.length > 0) new JavapSuccess(newPrinter(new ByteArrayInputStream(bytes)))
- else new JavapError("Could not find class bytes for '%s'".format(path))
+ class JpSuccess(val value: AnyRef) extends JpResult {
+ type ResultType = AnyRef
+ def isError = false
+ def show() = value.asInstanceOf[{ def print(): Unit }].print()
}
-}
-object Javap extends Javap(ScalaClassLoader.getSystemLoader()) {
- def apply(path: String): AnyRef = guess(path)
+ class JpOptions {
+ private object Access {
+ final val PRIVATE = 0
+ final val PROTECTED = 1
+ final val PACKAGE = 2
+ final val PUBLIC = 3
+ }
+ private val envActionMap: Map[String, (String, Any)] = {
+ val map = Map(
+ "-l" -> ("showLineAndLocal", true),
+ "-c" -> ("showDisassembled", true),
+ "-s" -> ("showInternalSigs", true),
+ "-verbose" -> ("showVerbose", true),
+ "-private" -> ("showAccess", Access.PRIVATE),
+ "-package" -> ("showAccess", Access.PACKAGE),
+ "-protected" -> ("showAccess", Access.PROTECTED),
+ "-public" -> ("showAccess", Access.PUBLIC),
+ "-all" -> ("showallAttr", true)
+ )
+ map ++ List(
+ "-v" -> map("-verbose"),
+ "-p" -> map("-private")
+ )
+ }
+ def apply(opts: Seq[String]): Seq[(String, Any)] = {
+ opts flatMap { opt =>
+ envActionMap get opt match {
+ case Some(pair) => List(pair)
+ case _ =>
+ val charOpts = opt.tail.toSeq map ("-" + _)
+ if (charOpts forall (envActionMap contains _))
+ charOpts map envActionMap
+ else Nil
+ }
+ }
+ }
+ }
}
diff --git a/test/files/run/javap.check b/test/files/run/javap.check
new file mode 100644
index 0000000000..1985fd611d
--- /dev/null
+++ b/test/files/run/javap.check
@@ -0,0 +1,18 @@
+Arguments: ''
+public class Bippy extends java.lang.Object implements scala.ScalaObject{
+public scala.collection.immutable.List f(scala.collection.immutable.List);
+public Bippy();
+Arguments: '-v'
+public class Bippy extends java.lang.Object implements scala.ScalaObject
+public #28= #25 of #27; //Bippy=class Bippy of class
+public scala.collection.immutable.List f(scala.collection.immutable.List);
+public Bippy();
+Arguments: '-s'
+public class Bippy extends java.lang.Object implements scala.ScalaObject{
+public scala.collection.immutable.List f(scala.collection.immutable.List);
+public Bippy();
+Arguments: '-private'
+public class Bippy extends java.lang.Object implements scala.ScalaObject{
+private int privateMethod();
+public scala.collection.immutable.List f(scala.collection.immutable.List);
+public Bippy();
diff --git a/test/files/run/javap.scala b/test/files/run/javap.scala
new file mode 100644
index 0000000000..241a83fa6f
--- /dev/null
+++ b/test/files/run/javap.scala
@@ -0,0 +1,24 @@
+import scala.tools.nsc.interpreter._
+
+object Test {
+ def run(args: String) = {
+ println("Arguments: '" + args + "'")
+ ILoop.run("""
+ |class Bippy {
+ | private def privateMethod = 5
+ | def f[T <: List[_]](x: T): T = x
+ |}
+ |
+ |:javap %s Bippy
+ """.stripMargin.format(args)).lines map (_.trim) filter { line =>
+ (line startsWith "private") || (line startsWith "public")
+ } foreach println
+ }
+
+ def main(args: Array[String]): Unit = {
+ run("")
+ run("-v")
+ run("-s")
+ run("-private")
+ }
+}