aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/util/ShowPickled.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-03-13 14:11:44 +0100
committerMartin Odersky <odersky@gmail.com>2013-03-13 14:11:44 +0100
commit3c7a8eada3630989b07bd3022797fd42a3b8cfcc (patch)
tree0036fee8aa025e3eea8502ea08f413f6baec3a56 /src/dotty/tools/dotc/util/ShowPickled.scala
parentd1794c15f5a5743763adeb8f8e248f9ca5f53869 (diff)
downloaddotty-3c7a8eada3630989b07bd3022797fd42a3b8cfcc.tar.gz
dotty-3c7a8eada3630989b07bd3022797fd42a3b8cfcc.tar.bz2
dotty-3c7a8eada3630989b07bd3022797fd42a3b8cfcc.zip
Various fixes to get past Definitions#init.
Diffstat (limited to 'src/dotty/tools/dotc/util/ShowPickled.scala')
-rw-r--r--src/dotty/tools/dotc/util/ShowPickled.scala294
1 files changed, 294 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/util/ShowPickled.scala b/src/dotty/tools/dotc/util/ShowPickled.scala
new file mode 100644
index 000000000..ab2801127
--- /dev/null
+++ b/src/dotty/tools/dotc/util/ShowPickled.scala
@@ -0,0 +1,294 @@
+package dotty.tools.dotc
+package util
+
+import java.io.{File, FileInputStream, PrintStream}
+import java.lang.Long.toHexString
+import java.lang.Float.intBitsToFloat
+import java.lang.Double.longBitsToDouble
+import scala.reflect.internal.Flags
+import scala.reflect.internal.pickling.PickleFormat
+import core.pickling.PickleBuffer
+import core.Names._
+
+object ShowPickled {
+ import PickleFormat._
+
+ case class PickleBufferEntry(num: Int, startIndex: Int, tag: Int, bytes: Array[Byte]) {
+ def isName = tag == TERMname || tag == TYPEname
+ def hasName = tag match {
+ case TYPEsym | ALIASsym | CLASSsym | MODULEsym | VALsym | EXTref | EXTMODCLASSref => true
+ case _ => false
+ }
+ def readName =
+ if (isName) new String(bytes, "UTF-8")
+ else sys.error("%s is no name" format tagName)
+ def nameIndex =
+ if (hasName) readNat(bytes, 0)
+ else sys.error("%s has no name" format tagName)
+
+ def tagName = tag2string(tag)
+ override def toString = "%d,%d: %s".format(num, startIndex, tagName)
+ }
+
+ case class PickleBufferEntryList(entries: IndexedSeq[PickleBufferEntry]) {
+ def nameAt(idx: Int) = {
+ val entry = entries(idx)
+ if (entry.isName) entry.readName
+ else if (entry.hasName) entries(entry.nameIndex).readName
+ else "?"
+ }
+ }
+
+ def makeEntryList(buf: PickleBuffer, index: Array[Int]) = {
+ val entries = buf.toIndexedSeq.zipWithIndex map {
+ case ((tag, data), num) => PickleBufferEntry(num, index(num), tag, data)
+ }
+
+ PickleBufferEntryList(entries)
+ }
+
+ def tag2string(tag: Int): String = tag match {
+ case TERMname => "TERMname"
+ case TYPEname => "TYPEname"
+ case NONEsym => "NONEsym"
+ case TYPEsym => "TYPEsym"
+ case ALIASsym => "ALIASsym"
+ case CLASSsym => "CLASSsym"
+ case MODULEsym => "MODULEsym"
+ case VALsym => "VALsym"
+ case EXTref => "EXTref"
+ case EXTMODCLASSref => "EXTMODCLASSref"
+ case NOtpe => "NOtpe"
+ case NOPREFIXtpe => "NOPREFIXtpe"
+ case THIStpe => "THIStpe"
+ case SINGLEtpe => "SINGLEtpe"
+ case CONSTANTtpe => "CONSTANTtpe"
+ case TYPEREFtpe => "TYPEREFtpe"
+ case TYPEBOUNDStpe => "TYPEBOUNDStpe"
+ case REFINEDtpe => "REFINEDtpe"
+ case CLASSINFOtpe => "CLASSINFOtpe"
+ case METHODtpe => "METHODtpe"
+ case POLYtpe => "POLYtpe"
+ case IMPLICITMETHODtpe => "METHODtpe" // IMPLICITMETHODtpe no longer used.
+ case SUPERtpe => "SUPERtpe"
+ case LITERALunit => "LITERALunit"
+ case LITERALboolean => "LITERALboolean"
+ case LITERALbyte => "LITERALbyte"
+ case LITERALshort => "LITERALshort"
+ case LITERALchar => "LITERALchar"
+ case LITERALint => "LITERALint"
+ case LITERALlong => "LITERALlong"
+ case LITERALfloat => "LITERALfloat"
+ case LITERALdouble => "LITERALdouble"
+ case LITERALstring => "LITERALstring"
+ case LITERALnull => "LITERALnull"
+ case LITERALclass => "LITERALclass"
+ case LITERALenum => "LITERALenum"
+ case SYMANNOT => "SYMANNOT"
+ case CHILDREN => "CHILDREN"
+ case ANNOTATEDtpe => "ANNOTATEDtpe"
+ case ANNOTINFO => "ANNOTINFO"
+ case ANNOTARGARRAY => "ANNOTARGARRAY"
+ // case DEBRUIJNINDEXtpe => "DEBRUIJNINDEXtpe"
+ case EXISTENTIALtpe => "EXISTENTIALtpe"
+ case TREE => "TREE"
+ case MODIFIERS => "MODIFIERS"
+
+ case _ => "***BAD TAG***(" + tag + ")"
+ }
+
+ /** Extremely regrettably, essentially copied from PickleBuffer.
+ */
+ def readNat(data: Array[Byte], index: Int): Int = {
+ var idx = index
+ var result = 0L
+ var b = 0L
+ do {
+ b = data(idx)
+ idx += 1
+ result = (result << 7) + (b & 0x7f)
+ } while((b & 0x80) != 0L)
+
+ result.toInt
+ }
+
+ def printFile(buf: PickleBuffer, out: PrintStream = System.out) {
+ out.println("Version " + buf.readNat() + "." + buf.readNat())
+ val index = buf.createIndex
+ val entryList = makeEntryList(buf, index)
+ buf.readIndex = 0
+
+ def p(s: String) = out print s
+
+ def printNameRef() {
+ val idx = buf.readNat()
+ val name = entryList nameAt idx
+ val toPrint = " %s(%s)".format(idx, name)
+
+ out print toPrint
+ }
+
+ def printNat() = p(" " + buf.readNat())
+ def printReadNat(x: Int) = p(" " + x)
+
+ def printSymbolRef() = printNat()
+ def printTypeRef() = printNat()
+ def printConstantRef() = printNat()
+ def printAnnotInfoRef() = printNat()
+ def printConstAnnotArgRef() = printNat()
+ def printAnnotArgRef() = printNat()
+
+ def printSymInfo(end: Int) {
+ printNameRef()
+ printSymbolRef()
+ val pflags = buf.readLongNat()
+ def printFlags(privateWithin: Option[Int]) = {
+ val accessBoundary = (
+ for (idx <- privateWithin) yield {
+ val s = entryList nameAt idx
+ idx + "(" + s + ")"
+ }
+ )
+ val flagString = {
+ val arg1 = Flags.pickledToRawFlags(pflags)
+ accessBoundary match {
+ case Some(pw) => Flags.flagsToString(arg1, pw)
+ case _ => Flags.flagsToString(arg1)
+ }
+ }
+
+ out.print(" %s[%s]".format(toHexString(pflags), flagString))
+ }
+
+ /** Might be info or privateWithin */
+ val x = buf.readNat()
+ if (buf.readIndex == end) {
+ printFlags(None)
+ printReadNat(x)
+ }
+ else {
+ printFlags(Some(x))
+ printTypeRef()
+ }
+ }
+
+ /** Note: the entries which require some semantic analysis to be correctly
+ * interpreted are for the most part going to tell you the wrong thing.
+ * It's not so easy to duplicate the logic applied in the UnPickler.
+ */
+ def printEntry(i: Int) {
+ buf.readIndex = index(i)
+ p(i + "," + buf.readIndex + ": ")
+ val tag = buf.readByte()
+ out.print(tag2string(tag))
+ val len = buf.readNat()
+ val end = len + buf.readIndex
+ p(" " + len + ":")
+ tag match {
+ case TERMname =>
+ out.print(" ")
+ out.print(termName(buf.bytes, buf.readIndex, len).toString)
+ buf.readIndex = end
+ case TYPEname =>
+ out.print(" ")
+ out.print(typeName(buf.bytes, buf.readIndex, len))
+ buf.readIndex = end
+ case TYPEsym | ALIASsym | CLASSsym | MODULEsym | VALsym =>
+ printSymInfo(end)
+ if (tag == CLASSsym && (buf.readIndex < end)) printTypeRef()
+ case EXTref | EXTMODCLASSref =>
+ printNameRef()
+ if (buf.readIndex < end) { printSymbolRef() }
+ case THIStpe =>
+ printSymbolRef()
+ case SINGLEtpe =>
+ printTypeRef(); printSymbolRef()
+ case CONSTANTtpe =>
+ printTypeRef(); printConstantRef()
+ case TYPEREFtpe =>
+ printTypeRef(); printSymbolRef(); buf.until(end, printTypeRef)
+ case TYPEBOUNDStpe =>
+ printTypeRef(); printTypeRef()
+ case REFINEDtpe =>
+ printSymbolRef(); buf.until(end, printTypeRef)
+ case CLASSINFOtpe =>
+ printSymbolRef(); buf.until(end, printTypeRef)
+ case METHODtpe | IMPLICITMETHODtpe =>
+ printTypeRef(); buf.until(end, printTypeRef)
+ case POLYtpe =>
+ printTypeRef(); buf.until(end, printSymbolRef)
+ case LITERALboolean =>
+ out.print(if (buf.readLong(len) == 0L) " false" else " true")
+ case LITERALbyte =>
+ out.print(" " + buf.readLong(len).toByte)
+ case LITERALshort =>
+ out.print(" " + buf.readLong(len).toShort)
+ case LITERALchar =>
+ out.print(" " + buf.readLong(len).toChar)
+ case LITERALint =>
+ out.print(" " + buf.readLong(len).toInt)
+ case LITERALlong =>
+ out.print(" " + buf.readLong(len))
+ case LITERALfloat =>
+ out.print(" " + intBitsToFloat(buf.readLong(len).toInt))
+ case LITERALdouble =>
+ out.print(" " + longBitsToDouble(buf.readLong(len)))
+ case LITERALstring =>
+ printNameRef()
+ case LITERALenum =>
+ printSymbolRef()
+ case LITERALnull =>
+ out.print(" <null>")
+ case LITERALclass =>
+ printTypeRef()
+ case CHILDREN =>
+ printSymbolRef(); buf.until(end, printSymbolRef)
+ case SYMANNOT =>
+ printSymbolRef(); printTypeRef(); buf.until(end, printAnnotArgRef)
+ case ANNOTATEDtpe =>
+ printTypeRef(); buf.until(end, printAnnotInfoRef);
+ case ANNOTINFO =>
+ printTypeRef(); buf.until(end, printAnnotArgRef)
+ case ANNOTARGARRAY =>
+ buf.until(end, printConstAnnotArgRef)
+ case EXISTENTIALtpe =>
+ printTypeRef(); buf.until(end, printSymbolRef)
+
+ case _ =>
+ }
+ out.println()
+ if (buf.readIndex != end) {
+ out.println("BAD ENTRY END: computed = %d, actual = %d, bytes = %s".format(
+ end, buf.readIndex, buf.bytes.slice(index(i), (end max buf.readIndex)).mkString(", ")
+ ))
+ }
+ }
+
+ for (i <- 0 until index.length) printEntry(i)
+ }
+
+/*
+ *
+ def fromFile(path: String) = fromBytes(io.File(path).toByteArray)
+ def fromName(name: String) = fromBytes(scalaSigBytesForPath(name) getOrElse Array())
+ def fromBytes(data: => Array[Byte]): Option[PickleBuffer] =
+ try Some(new PickleBuffer(data, 0, data.length))
+ catch { case _: Exception => None }
+
+ def show(what: String, pickle: PickleBuffer) = {
+ Console.println(what)
+ val saved = pickle.readIndex
+ pickle.readIndex = 0
+ printFile(pickle, Console.out)
+ pickle.readIndex = saved
+ }
+
+ def main(args: Array[String]) {
+ args foreach { arg =>
+ (fromFile(arg) orElse fromName(arg)) match {
+ case Some(pb) => show(arg + ":", pb)
+ case _ => Console.println("Cannot read " + arg)
+ }
+ }
+ }*/
+}