summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-02-15 20:00:36 +0000
committerPaul Phillips <paulp@improving.org>2010-02-15 20:00:36 +0000
commit821229741d41ab5a0087ddf289ee01b92e9c0685 (patch)
tree1306ddc619017d903c2bceb35ba37ba27cc27dbf
parent369d3ca26f05ab848807c109e464f90f2e668c81 (diff)
downloadscala-821229741d41ab5a0087ddf289ee01b92e9c0685.tar.gz
scala-821229741d41ab5a0087ddf289ee01b92e9c0685.tar.bz2
scala-821229741d41ab5a0087ddf289ee01b92e9c0685.zip
Some new tools for the tools directory.
amounts to a yak shaving expedition to enable this, which now works: tools/diffPickled scala.Either and since stability is presently broken you will see the following. (When it's not broken you will see nothing.) 541,544c541,544 < 538,4090: EXTref 3: 539(Left) 2 < 539,4095: TYPEname 4: Left < 540,4101: EXTref 3: 541(Right) 2 < 541,4106: TYPEname 5: Right --- > 538,4090: EXTref 3: 539(Right) 2 > 539,4095: TYPEname 5: Right > 540,4102: EXTref 3: 541(Left) 2 > 541,4107: TYPEname 4: Left
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ByteCode.scala10
-rw-r--r--src/compiler/scala/tools/nsc/util/ShowPickled.scala26
-rw-r--r--src/scalap/scala/tools/scalap/Classfile.scala1
-rw-r--r--src/scalap/scala/tools/scalap/Decode.scala12
-rwxr-xr-xtools/abspath9
-rwxr-xr-xtools/cpof30
-rwxr-xr-xtools/diffPickled51
-rwxr-xr-xtools/packcp5
-rwxr-xr-xtools/quickcp5
-rwxr-xr-xtools/showPickled32
-rwxr-xr-xtools/starrcp5
-rwxr-xr-xtools/strapcp5
12 files changed, 182 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala
index dc4e173fff..4b8e0ae60c 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala
@@ -29,6 +29,16 @@ object ByteCode {
method.invoke(module, _: String).asInstanceOf[Option[Map[String, String]]]
}
+ /** Scala sig bytes.
+ */
+ def scalaSigBytesForPath(path: String) =
+ for {
+ module <- DECODER
+ method <- decoderMethod("scalaSigBytes", classOf[String])
+ names <- method.invoke(module, path).asInstanceOf[Option[Array[Byte]]]
+ }
+ yield names
+
/** Attempts to retrieve case parameter names for given class name.
*/
def caseParamNamesForPath(path: String) =
diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala
index f99f63dcda..20ae9c7eeb 100644
--- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala
+++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala
@@ -14,6 +14,7 @@ import java.lang.Double.longBitsToDouble
import symtab.{Flags, Names}
import symtab.classfile.{PickleBuffer, PickleFormat}
+import interpreter.ByteCode.scalaSigBytesForPath
object ShowPickled extends Names {
@@ -193,17 +194,26 @@ object ShowPickled extends Names {
for (i <- 0 until index.length) printEntry(i)
}
- def main(args: Array[String]) {
- val file = new File(args(0))
+ def fromBytes(what: String, data: => Array[Byte]): Boolean = {
try {
- val stream = new FileInputStream(file)
- val data = new Array[Byte](stream.available())
- stream.read(data)
val pickle = new PickleBuffer(data, 0, data.length)
+ Console.println(what + ": ")
printFile(pickle, Console.out)
- } catch {
- case ex: IOException =>
- Console.println("cannot read " + file + ": " + ex.getMessage())
+ true
+ }
+ catch {
+ case _: Exception => false
+ }
+ }
+
+ def fromFile(path: String) = fromBytes(path, io.File(path).toByteArray)
+ def fromName(name: String) = fromBytes(name, scalaSigBytesForPath(name) getOrElse Array())
+
+ def main(args: Array[String]) {
+ args foreach { arg =>
+ val res = fromFile(arg) || fromName(arg)
+ if (!res)
+ Console.println("Cannot read " + arg)
}
}
}
diff --git a/src/scalap/scala/tools/scalap/Classfile.scala b/src/scalap/scala/tools/scalap/Classfile.scala
index 44f687bd85..c4f273c5aa 100644
--- a/src/scalap/scala/tools/scalap/Classfile.scala
+++ b/src/scalap/scala/tools/scalap/Classfile.scala
@@ -26,6 +26,7 @@ class Classfile(in: ByteArrayReader) {
val fields = readMembers(true)
val methods = readMembers(false)
val attribs = readAttribs
+ def scalaSigAttribute = attribs find (_.toString == Main.SCALA_SIG)
def readAttribs = {
val n = in.nextChar
diff --git a/src/scalap/scala/tools/scalap/Decode.scala b/src/scalap/scala/tools/scalap/Decode.scala
index 04d72c015b..6e55558249 100644
--- a/src/scalap/scala/tools/scalap/Decode.scala
+++ b/src/scalap/scala/tools/scalap/Decode.scala
@@ -10,7 +10,8 @@
package scala.tools.scalap
import scala.tools.scalap.scalax.rules.scalasig._
-import scala.tools.nsc.util.ScalaClassLoader.getSystemLoader
+import scala.tools.nsc.util.ScalaClassLoader.{ getSystemLoader, findBytesForClassName }
+import Main.SCALA_SIG
/** Temporary decoder. This would be better off in the scala.tools.nsc
* but right now the compiler won't acknowledge scala.tools.scalap
@@ -23,6 +24,15 @@ object Decode {
case _ => NoSymbol
}
+ /** Return the classfile bytes representing the scala sig attribute.
+ */
+ def scalaSigBytes(name: String): Option[Array[Byte]] = {
+ val bytes = findBytesForClassName(name)
+ val reader = new ByteArrayReader(bytes)
+ val cf = new Classfile(reader)
+ cf.scalaSigAttribute map (_.data)
+ }
+
/** private[scala] so nobody gets the idea this is a supported interface.
*/
private[scala] def caseParamNames(path: String): Option[List[String]] = {
diff --git a/tools/abspath b/tools/abspath
new file mode 100755
index 0000000000..a2d1410b9b
--- /dev/null
+++ b/tools/abspath
@@ -0,0 +1,9 @@
+#!/bin/sh
+#
+# print the absolute path of each argument
+
+for relpath in $* ; do
+ D=`dirname "$relpath"`
+ B=`basename "$relpath"`
+ echo "`cd \"$D\" 2>/dev/null && pwd || echo \"$D\"`/$B"
+done \ No newline at end of file
diff --git a/tools/cpof b/tools/cpof
new file mode 100755
index 0000000000..ab5a42b4fb
--- /dev/null
+++ b/tools/cpof
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Creates a classpath out of the contents of each directory
+# given as an argument.
+
+if [ $# == 0 ] ; then
+ echo "Usage: $0 [dir1 dir2 ...]"
+ exit 1
+fi
+
+THISDIR=`dirname $0`
+ABSCMD="${THISDIR}/abspath"
+CPRES=""
+
+for dir in $* ; do
+ absdir=`${ABSCMD} $dir`
+ LS=`ls -1 ${absdir}`
+
+ for x in $LS ; do
+ ABS=`${ABSCMD} "${absdir}/${x}"`
+ CPRES="${CPRES}:${ABS}"
+ done
+done
+
+# shaving the : off the beginning. Applause to /bin/sh for
+# keeping us humble about how far we've come.
+LEN=$(( ${#CPRES} - 1 ))
+result=${CPRES:1:${LEN}}
+
+echo $result
diff --git a/tools/diffPickled b/tools/diffPickled
new file mode 100755
index 0000000000..b4a345dc7d
--- /dev/null
+++ b/tools/diffPickled
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Shows the difference in pickler output between two variations on a class.
+#
+# If quick and strap are built normally you can run
+#
+# diffPickled foo.bar.Baz
+#
+# to see any differences between them in that class.
+
+USAGE="Usage: $0 classpath1 classpath2 class"
+TOOLSDIR=`dirname $0`
+BUILDDIR="${TOOLSDIR}/../build"
+QUICKDIR="${BUILDDIR}/quick"
+STRAPDIR="${BUILDDIR}/strap"
+
+CP1=""
+CP2=""
+CLASS=""
+
+if [ $# == 1 ] ; then
+ if [ -e ${QUICKDIR} ] && [ -e ${STRAPDIR} ] ; then
+ CP1=`${TOOLSDIR}/quickcp`
+ CP2=`${TOOLSDIR}/strapcp`
+ CLASS=$1
+ else
+ echo $USAGE
+ echo "(If only one argument is given, $QUICKDIR and $STRAPDIR must exist.)"
+ exit 1
+ fi
+elif [ $# == 3 ] ; then
+ CP1=$1
+ CP2=$2
+ CLASS=$3
+else
+ echo $USAGE
+ exit 1
+fi
+
+TMPDIR="/tmp/scala_pickle_diff${RANDOM}"
+
+if mkdir -m 0700 "$TMPDIR" 2>/dev/null ; then
+ ${TOOLSDIR}/showPickled -cp $CP1 $CLASS > "${TMPDIR}/out1.txt"
+ ${TOOLSDIR}/showPickled -cp $CP2 $CLASS > "${TMPDIR}/out2.txt"
+ diff "${TMPDIR}/out1.txt" "${TMPDIR}/out2.txt"
+ rm -rf ${TMPDIR}
+else
+ echo "Failed to create temporary directory ${TMPDIR}."
+ exit 1
+fi
+
diff --git a/tools/packcp b/tools/packcp
new file mode 100755
index 0000000000..42bce9e266
--- /dev/null
+++ b/tools/packcp
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+
+THISDIR=`dirname $0`
+${THISDIR}/cpof ${THISDIR}/../build/pack/lib
diff --git a/tools/quickcp b/tools/quickcp
new file mode 100755
index 0000000000..9d7ff8dfb0
--- /dev/null
+++ b/tools/quickcp
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+
+THISDIR=`dirname $0`
+${THISDIR}/cpof ${THISDIR}/../build/quick/classes
diff --git a/tools/showPickled b/tools/showPickled
new file mode 100755
index 0000000000..67d86355ba
--- /dev/null
+++ b/tools/showPickled
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Shows the pickled scala data in a classfile.
+
+if [ $# == 0 ] ; then
+ echo "Usage: $0 [-cp classpath] class class [...]"
+ exit 1
+fi
+
+TOOLSDIR=`dirname $0`
+CPOF="$TOOLSDIR/cpof"
+
+PACK="$TOOLSDIR/../build/pack/lib"
+QUICK="$TOOLSDIR/../build/quick/classes"
+STARR="$TOOLSDIR/../lib"
+CP=""
+
+if [ -f "${PACK}/scala-library.jar" ] ; then
+ CP=`${TOOLSDIR}/packcp`
+elif [ -d "${QUICK}/library" ] ; then
+ CP=`${TOOLSDIR}/quickcp`
+else
+ CP=`${TOOLSDIR}/starrcp`
+fi
+
+if [ "$1" == "-cp" ] ; then
+ shift
+ CP="${1}:${CP}"
+ shift
+fi
+
+java -cp "$CP" scala.tools.nsc.util.ShowPickled $*
diff --git a/tools/starrcp b/tools/starrcp
new file mode 100755
index 0000000000..6add5665b5
--- /dev/null
+++ b/tools/starrcp
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+
+THISDIR=`dirname $0`
+${THISDIR}/cpof ${THISDIR}/../lib \ No newline at end of file
diff --git a/tools/strapcp b/tools/strapcp
new file mode 100755
index 0000000000..87e6ef720e
--- /dev/null
+++ b/tools/strapcp
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+
+THISDIR=`dirname $0`
+${THISDIR}/cpof ${THISDIR}/../build/strap/classes