diff options
-rw-r--r-- | sources/scala/tools/scalap/AbstractFile.scala | 105 | ||||
-rw-r--r-- | sources/scala/tools/scalap/ByteArrayReader.scala | 13 | ||||
-rw-r--r-- | sources/scala/tools/scalap/ClassPath.scala | 141 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Classfile.scala | 161 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Classfiles.scala | 8 | ||||
-rw-r--r-- | sources/scala/tools/scalap/CodeWriter.scala | 40 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Entity.scala | 46 | ||||
-rw-r--r-- | sources/scala/tools/scalap/EntityTable.scala | 186 | ||||
-rw-r--r-- | sources/scala/tools/scalap/FileCache.scala | 21 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Flags.scala | 89 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Main.scala | 75 | ||||
-rw-r--r-- | sources/scala/tools/scalap/Names.scala | 131 | ||||
-rw-r--r-- | sources/scala/tools/scalap/ScalaAttribute.scala | 170 | ||||
-rw-r--r-- | sources/scala/tools/scalap/ScalaWriter.scala | 388 |
14 files changed, 839 insertions, 735 deletions
diff --git a/sources/scala/tools/scalap/AbstractFile.scala b/sources/scala/tools/scalap/AbstractFile.scala index 38e2acebf6..75bd001c69 100644 --- a/sources/scala/tools/scalap/AbstractFile.scala +++ b/sources/scala/tools/scalap/AbstractFile.scala @@ -1,5 +1,10 @@ -// AbstractFile -// 04-Feb-2002, Matthias Zenger +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ package scalap; @@ -74,7 +79,7 @@ class PlainFile(f: File) with AbstractFile { def elements = { val fs = f.listFiles(); if (fs == null) - Iterator.empty[String] + Iterator.empty[String] else new Iterator[String] { var i = 0; @@ -109,32 +114,32 @@ class JarArchive(f: File) with AbstractFile { //entries = new mutable.HashMap[String, JarArchiveEntry]; entries = new mutable.JavaMapAdaptor(new java.util.HashMap()); if (jarFile != null) { - val enum = jarFile.entries(); - while (enum.hasMoreElements()) { - val candidate = enum.nextElement().asInstanceOf[JarEntry].getName(); - var i = candidate.indexOf('/'); - var j = 0; - var files = entries; - while (i >= 0) { - val dirname = candidate.substring(j, i + 1); - j = i + 1; - if (!files.isDefinedAt(dirname)) - files(dirname) = new JarDirEntry(candidate.substring(0, j)); - files = files(dirname).entries; - i = candidate.indexOf('/', j); - } - if (j < (candidate.length() - 1)) { - val filename = candidate.substring(j); - if (!files.isDefinedAt(filename)) - files(filename) = new JarFileEntry(candidate); - } - } + val enum = jarFile.entries(); + while (enum.hasMoreElements()) { + val candidate = enum.nextElement().asInstanceOf[JarEntry].getName(); + var i = candidate.indexOf('/'); + var j = 0; + var files = entries; + while (i >= 0) { + val dirname = candidate.substring(j, i + 1); + j = i + 1; + if (!files.isDefinedAt(dirname)) + files(dirname) = new JarDirEntry(candidate.substring(0, j)); + files = files(dirname).entries; + i = candidate.indexOf('/', j); + } + if (j < (candidate.length() - 1)) { + val filename = candidate.substring(j); + if (!files.isDefinedAt(filename)) + files(filename) = new JarFileEntry(candidate); + } + } } } def list(prefix: String) = { - val pref = prefix.replace(File.separatorChar, '/'); - if (entries == null) + val pref = prefix.replace(File.separatorChar, '/'); + if (entries == null) load; var i = pref.indexOf('/'); var j = 0; @@ -145,19 +150,19 @@ class JarArchive(f: File) with AbstractFile { j = i + 1; continue = files.isDefinedAt(dirname); if (continue) { - files = files(dirname).entries; - i = pref.indexOf('/', j); + files = files(dirname).entries; + i = pref.indexOf('/', j); } } if (!continue) - Iterator.empty; + Iterator.empty; else if (j < (pref.length() - 1)) { if (files.isDefinedAt(pref.substring(j))) - List(pref).elements; + List(pref).elements; else Iterator.empty; } else - files.keys; + files.keys; } def elements = list(""); @@ -175,36 +180,36 @@ class JarArchive(f: File) with AbstractFile { val dirname = name.substring(j, i + 1); j = i + 1; if (files != null) { - if (files.isDefinedAt(dirname)) { - if (j == namelen) - res = files(dirname); - else - files = files(dirname).entries; - } else - files = null; + if (files.isDefinedAt(dirname)) { + if (j == namelen) + res = files(dirname); + else + files = files(dirname).entries; + } else + files = null; } i = name.indexOf('/', j); } if (res != null) - res + res else if (j < (namelen - 1)) { - if (files == null) - new JarArchiveEntry(name, false); - else { - val filename = name.substring(j); - if (files.isDefinedAt(filename)) - files(filename) - else - new JarArchiveEntry(name, false) - } + if (files == null) + new JarArchiveEntry(name, false); + else { + val filename = name.substring(j); + if (files.isDefinedAt(filename)) + files(filename) + else + new JarArchiveEntry(name, false) + } } else new JarArchiveEntry(name, true); } - class JarArchiveEntry(name: String, dir: Boolean) with AbstractFile { + class JarArchiveEntry(name: String, dir: Boolean) with AbstractFile { def getName = name.substring( - name.lastIndexOf('/', name.length() - (if (dir) 2 else 1)) + 1); + name.lastIndexOf('/', name.length() - (if (dir) 2 else 1)) + 1); def getPath = name; @@ -234,7 +239,7 @@ class JarArchive(f: File) with AbstractFile { override def elements = JarArchive.this.list(name); override def open(fname: String) = JarArchive.this.open( - name + fname.replace(File.separatorChar, '/')); + name + fname.replace(File.separatorChar, '/')); override def entries: mutable.Map[String, JarArchiveEntry] = entr; } diff --git a/sources/scala/tools/scalap/ByteArrayReader.scala b/sources/scala/tools/scalap/ByteArrayReader.scala index 71938dbe82..480bcd8950 100644 --- a/sources/scala/tools/scalap/ByteArrayReader.scala +++ b/sources/scala/tools/scalap/ByteArrayReader.scala @@ -1,7 +1,16 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; + class ByteArrayReader(content: Array[Byte]) { - import java.io._; + import java.io._; /** the buffer containing the file */ @@ -76,7 +85,7 @@ class ByteArrayReader(content: Array[Byte]) { /** read an UTF8 encoded string */ - def nextUTF8(len: Int): String = { + def nextUTF8(len: Int): String = { val cs: Array[Char] = new Array(len); var i = bp; var j = 0; diff --git a/sources/scala/tools/scalap/ClassPath.scala b/sources/scala/tools/scalap/ClassPath.scala index 74c81de732..4a907a93af 100644 --- a/sources/scala/tools/scalap/ClassPath.scala +++ b/sources/scala/tools/scalap/ClassPath.scala @@ -1,5 +1,10 @@ -// ClassPath -// 04-Mar-2002, Matthias Zenger +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ package scalap; @@ -32,7 +37,7 @@ class ClassPath { /** the corresponding file cache (for not reading .jar files over * and over again) */ - val cache = new FileCache; + val cache = new FileCache; /** the various class path roots */ @@ -45,7 +50,7 @@ class ClassPath { */ protected def expand(edirs: String): List[String] = if (edirs == null) - Nil + Nil else { val extdirs = edirs + PATH_SEP; val length = extdirs.length(); @@ -58,8 +63,8 @@ class ClassPath { val iter = Iterator.fromArray(new File(dirname).list()); val dname = if (dirname.endsWith(FILE_SEP)) dirname else dirname + FILE_SEP; while (iter.hasNext) { - val entry = iter.next; - if (entry.endsWith(".jar")) + val entry = iter.next; + if (entry.endsWith(".jar")) path = (dname + entry) :: path; } } @@ -72,14 +77,14 @@ class ClassPath { * of existing class file locations */ protected def decompose(p: String): List[String] = { - val path = if (p.endsWith(PATH_SEP)) p else p + PATH_SEP; - var components: List[String] = Nil; + val path = if (p.endsWith(PATH_SEP)) p else p + PATH_SEP; + var components: List[String] = Nil; var i = 0; while (i < path.length()) { val j = path.indexOf(PATH_SEP, i); val subpath = path.substring(i, j); if (new File(subpath).exists()) - components = subpath :: components; + components = subpath :: components; i = j + 1; } components.reverse; @@ -90,17 +95,17 @@ class ClassPath { * component. */ def findFile(name: String): Pair[AbstractFile, String] = { - val iter = root.elements; - var entry: AbstractFile = null; - var continue: Boolean = true; - var origin: String = null; - while (continue && iter.hasNext) { - origin = iter.next; - entry = cache.open(origin, name); - if (entry.exists) - continue = false; - } - Pair(entry, origin) + val iter = root.elements; + var entry: AbstractFile = null; + var continue: Boolean = true; + var origin: String = null; + while (continue && iter.hasNext) { + origin = iter.next; + entry = cache.open(origin, name); + if (entry.exists) + continue = false; + } + Pair(entry, origin) } /** find file with given name in class path and return an abstract @@ -112,64 +117,64 @@ class ClassPath { * file representation. */ def openClass(name: String): AbstractFile = - openFile(name.replace('.', File.separatorChar) + ".class"); + openFile(name.replace('.', File.separatorChar) + ".class"); def elements: Iterator[String] = root.elements; def classes: Iterator[String] = new Iterator[String] { - val todo: mutable.Stack[Pair[AbstractFile, String]] = new mutable.Stack; - var iter: Iterator[String] = Iterator.empty; - var file: AbstractFile = null; - var path: String = null; - var clazz: String = null; + val todo: mutable.Stack[Pair[AbstractFile, String]] = new mutable.Stack; + var iter: Iterator[String] = Iterator.empty; + var file: AbstractFile = null; + var path: String = null; + var clazz: String = null; root.foreach { component => { - val f = cache.open(component, null); - if (f.exists && f.isDirectory) - todo.push(Pair(f, null)); + val f = cache.open(component, null); + if (f.exists && f.isDirectory) + todo.push(Pair(f, null)); }}; - scan; - def hasNext = (clazz != null); - def next = - if (clazz == null) - error("no next element"); - else { - val res = clazz; scan; res - }; - def scan: Unit = { - if (!iter.hasNext) { - if (todo.isEmpty) - clazz = null; - else { - val Pair(f, p) = todo.top; - todo.pop; - iter = f.elements; - file = f; - path = if ((p != null) && p.endsWith("/")) - p.substring(0, p.length() - 1) else p; - scan; - } - } else { - var continue = true; - while (continue && iter.hasNext) { - val g = file.open(iter.next); - clazz = if (path == null) g.getName else path + "." + g.getName; - if (clazz.endsWith(".class")) { - clazz = clazz.substring(0, clazz.length() - 6); - continue = false; - } else if (g.exists && g.isDirectory) - todo.push(Pair(g, clazz)); - } - if (continue) - scan; - } - } + scan; + def hasNext = (clazz != null); + def next = + if (clazz == null) + error("no next element"); + else { + val res = clazz; scan; res + }; + def scan: Unit = { + if (!iter.hasNext) { + if (todo.isEmpty) + clazz = null; + else { + val Pair(f, p) = todo.top; + todo.pop; + iter = f.elements; + file = f; + path = if ((p != null) && p.endsWith("/")) + p.substring(0, p.length() - 1) else p; + scan; + } + } else { + var continue = true; + while (continue && iter.hasNext) { + val g = file.open(iter.next); + clazz = if (path == null) g.getName else path + "." + g.getName; + if (clazz.endsWith(".class")) { + clazz = clazz.substring(0, clazz.length() - 6); + continue = false; + } else if (g.exists && g.isDirectory) + todo.push(Pair(g, clazz)); + } + if (continue) + scan; + } + } } /** return a textual representation of this class path */ override def toString() = root match { - case Nil => "" - case x :: Nil => x - case x :: xs => xs.foldLeft(x)((s, e) => s + PATH_SEP + e); + case Nil => "" + case x :: Nil => x + case x :: xs => xs.foldLeft(x)((s, e) => s + PATH_SEP + e); } } diff --git a/sources/scala/tools/scalap/Classfile.scala b/sources/scala/tools/scalap/Classfile.scala index c37459ba92..26a53a8f53 100644 --- a/sources/scala/tools/scalap/Classfile.scala +++ b/sources/scala/tools/scalap/Classfile.scala @@ -1,84 +1,93 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; + class Classfile(in: ByteArrayReader) { - import Classfiles._; + import Classfiles._; - assert(in.nextInt == JAVA_MAGIC); - val minorVersion = in.nextChar; - val majorVersion = in.nextChar; - val pool = readPool; - val flags = in.nextChar; - val classname = in.nextChar; - val superclass = in.nextChar; - val interfaces = readInterfaces; - val fields = readMembers(true); - val methods = readMembers(false); - val attribs = readAttribs; + assert(in.nextInt == JAVA_MAGIC); + val minorVersion = in.nextChar; + val majorVersion = in.nextChar; + val pool = readPool; + val flags = in.nextChar; + val classname = in.nextChar; + val superclass = in.nextChar; + val interfaces = readInterfaces; + val fields = readMembers(true); + val methods = readMembers(false); + val attribs = readAttribs; - def readAttribs = { - val n = in.nextChar; - var attribs: List[Attribute] = Nil; - var i = 0; - while (i < n) { - attribs = Attribute(in.nextChar, in.nextBytes(in.nextInt)) :: attribs; - i = i + 1; - } - attribs - } + def readAttribs = { + val n = in.nextChar; + var attribs: List[Attribute] = Nil; + var i = 0; + while (i < n) { + attribs = Attribute(in.nextChar, in.nextBytes(in.nextInt)) :: attribs; + i = i + 1; + } + attribs + } - def readMembers(field: Boolean) = { - val n = in.nextChar; - var members: List[Member] = Nil; - var i = 0; - while (i < n) { - members = Member(field, in.nextChar, in.nextChar, in.nextChar, readAttribs) :: members; - i = i + 1; - } - members - } + def readMembers(field: Boolean) = { + val n = in.nextChar; + var members: List[Member] = Nil; + var i = 0; + while (i < n) { + members = Member(field, in.nextChar, in.nextChar, in.nextChar, readAttribs) :: members; + i = i + 1; + } + members + } - def readInterfaces = { - val n = in.nextChar; - var intfs: List[Int] = Nil; - var i = 0; - while (i < n) { - intfs = in.nextChar :: intfs; - i = i + 1; - } - intfs - } + def readInterfaces = { + val n = in.nextChar; + var intfs: List[Int] = Nil; + var i = 0; + while (i < n) { + intfs = in.nextChar :: intfs; + i = i + 1; + } + intfs + } - def readPool = { - val pool = new Array[PoolEntry](in.nextChar); - var i = 1; + def readPool = { + val pool = new Array[PoolEntry](in.nextChar); + var i = 1; while (i < pool.length) { val tag: Int = in.nextByte; tag match { case 1 => // CONSTANT_UTF8 - pool(i) = UTF8(in.nextUTF8(in.nextChar)); + pool(i) = UTF8(in.nextUTF8(in.nextChar)); case 2 => // CONSTANT_UNICODE in.skip(in.nextChar); pool(i) = Empty(); case 7 => // CONSTANT_CLASS - pool(i) = ClassRef(in.nextChar); + pool(i) = ClassRef(in.nextChar); case 8 => // CONSTANT_STRING pool(i) = StringConst(in.nextChar); case 9 => // CONSTANT_FIELDREF - pool(i) = FieldRef(in.nextChar, in.nextChar); + pool(i) = FieldRef(in.nextChar, in.nextChar); case 10 => // CONSTANT_METHODREF - pool(i) = MethodRef(in.nextChar, in.nextChar); + pool(i) = MethodRef(in.nextChar, in.nextChar); case 11 => // CONSTANT_INTFMETHODREF - pool(i) = IntfMethodRef(in.nextChar, in.nextChar); + pool(i) = IntfMethodRef(in.nextChar, in.nextChar); case 12 => // CONSTANT_NAMEANDTYPE - pool(i) = NameAndType(in.nextChar, in.nextChar); + pool(i) = NameAndType(in.nextChar, in.nextChar); case 3 => // CONSTANT_INTEGER - pool(i) = IntegerConst(in.nextInt); + pool(i) = IntegerConst(in.nextInt); case 4 => // CONSTANT_FLOAT pool(i) = FloatConst(in.nextFloat); case 5 => // CONSTANT_LONG - pool(i) = LongConst(in.nextLong); - i = i + 1; - pool(i) = Empty(); + pool(i) = LongConst(in.nextLong); + i = i + 1; + pool(i) = Empty(); case 6 => // CONSTANT_DOUBLE pool(i) = DoubleConst(in.nextDouble); i = i + 1; @@ -87,30 +96,30 @@ class Classfile(in: ByteArrayReader) { i = i + 1; } pool - } + } - class PoolEntry; - case class UTF8(str: String) extends PoolEntry; - case class ClassRef(classId: Int) extends PoolEntry; - case class FieldRef(classId: Int, memberId: Int) extends PoolEntry; - case class MethodRef(classId: Int, memberId: Int) extends PoolEntry; - case class IntfMethodRef(classId: Int, memberId: Int) extends PoolEntry; - case class StringConst(strId: Int) extends PoolEntry; - case class IntegerConst(x: Int) extends PoolEntry; - case class FloatConst(x: Float) extends PoolEntry; - case class LongConst(x: Long) extends PoolEntry; - case class DoubleConst(x: Double) extends PoolEntry; - case class NameAndType(nameId: Int, typeId: Int) extends PoolEntry; - case class Empty() extends PoolEntry; + class PoolEntry; + case class UTF8(str: String) extends PoolEntry; + case class ClassRef(classId: Int) extends PoolEntry; + case class FieldRef(classId: Int, memberId: Int) extends PoolEntry; + case class MethodRef(classId: Int, memberId: Int) extends PoolEntry; + case class IntfMethodRef(classId: Int, memberId: Int) extends PoolEntry; + case class StringConst(strId: Int) extends PoolEntry; + case class IntegerConst(x: Int) extends PoolEntry; + case class FloatConst(x: Float) extends PoolEntry; + case class LongConst(x: Long) extends PoolEntry; + case class DoubleConst(x: Double) extends PoolEntry; + case class NameAndType(nameId: Int, typeId: Int) extends PoolEntry; + case class Empty() extends PoolEntry; - case class Member(field: Boolean, flags: Int, name: Int, tpe: Int, attribs: List[Attribute]); - case class Attribute(name: Int, data: Array[Byte]) { + case class Member(field: Boolean, flags: Int, name: Int, tpe: Int, attribs: List[Attribute]); + case class Attribute(name: Int, data: Array[Byte]) { - override def toString(): String = pool(name) match { - case UTF8(str: String) => str - } + override def toString(): String = pool(name) match { + case UTF8(str: String) => str + } - def reader: ByteArrayReader = new ByteArrayReader(data); - } + def reader: ByteArrayReader = new ByteArrayReader(data); + } } diff --git a/sources/scala/tools/scalap/Classfiles.scala b/sources/scala/tools/scalap/Classfiles.scala index ea3526131c..3aef2679db 100644 --- a/sources/scala/tools/scalap/Classfiles.scala +++ b/sources/scala/tools/scalap/Classfiles.scala @@ -1,3 +1,11 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; diff --git a/sources/scala/tools/scalap/CodeWriter.scala b/sources/scala/tools/scalap/CodeWriter.scala index d0f5bb99a8..759324bd7b 100644 --- a/sources/scala/tools/scalap/CodeWriter.scala +++ b/sources/scala/tools/scalap/CodeWriter.scala @@ -1,3 +1,11 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; import java.io._; @@ -17,9 +25,9 @@ class CodeWriter(writer: Writer) { def getIndentLevel = level; def setIndentLevel(level: Int): CodeWriter = { - this.level = level; - this - } + this.level = level; + this + } def getIndentWidth = if (step == null) -1 else step.length(); @@ -52,17 +60,17 @@ class CodeWriter(writer: Writer) { if (step == null) newspace; else if (!line) { - try { - writer.write(nl); - } catch { - case e => error("IO error") - } + try { + writer.write(nl); + } catch { + case e => error("IO error") + } line = align; align = true; space = false; this } else - this + this } def newspace: CodeWriter = { @@ -109,12 +117,12 @@ class CodeWriter(writer: Writer) { def print(value: Double): CodeWriter = print(String.valueOf(value)); def print(value: String): CodeWriter = try { - if (align) { - var i = 0; - while (i < level) { - writer.write(step); - i = i + 1; - } + if (align) { + var i = 0; + while (i < level) { + writer.write(step); + i = i + 1; + } } if (space) writer.write(" "); @@ -124,7 +132,7 @@ class CodeWriter(writer: Writer) { line = false; this } catch { - case e => error("IO error") + case e => error("IO error") } override def toString(): String = writer.toString(); diff --git a/sources/scala/tools/scalap/Entity.scala b/sources/scala/tools/scalap/Entity.scala index 6475894845..d26d1acb7c 100644 --- a/sources/scala/tools/scalap/Entity.scala +++ b/sources/scala/tools/scalap/Entity.scala @@ -1,3 +1,11 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; import java.io._; @@ -7,10 +15,10 @@ import scala.collection.mutable._; /** Entities are either text, symbols, or types. */ trait Entity { - def isText: Boolean = false; - def isType: Boolean = false; - def isSymbol: Boolean = false; - def toSource: String = toString(); + def isText: Boolean = false; + def isType: Boolean = false; + def isSymbol: Boolean = false; + def toSource: String = toString(); } /** Text refers to a single string. @@ -25,10 +33,10 @@ case class Text(str: String) extends Entity { trait Type extends Entity { override def isType: Boolean = true; override def toSource: String = { - val writer = new ScalaWriter(new StringWriter()); - writer.setIndentString(null)*; - writer.printType(this); - writer.toString() + val writer = new ScalaWriter(new StringWriter()); + writer.setIndentString(null)*; + writer.printType(this); + writer.toString() } } @@ -56,15 +64,15 @@ abstract case class Symbol(name: String, flags: Int) extends Entity { var tpe: Type = NoType; var owner: Symbol = NoSymbol; def fullname: String = owner match { - case s: ClassSymbol => { - val prefix = s.fullname; - if (prefix.length() == 0) name else (prefix + "." + name) - } - case s: ExternalSymbol => { - val prefix = s.fullname; - if (prefix.length() == 0) name else (prefix + "." + name) - } - case _ => name + case s: ClassSymbol => { + val prefix = s.fullname; + if (prefix.length() == 0) name else (prefix + "." + name) + } + case s: ExternalSymbol => { + val prefix = s.fullname; + if (prefix.length() == 0) name else (prefix + "." + name) + } + case _ => name } def fix(tpe: Type, owner: Symbol): Unit = { this.tpe = tpe; @@ -80,7 +88,7 @@ abstract case class Symbol(name: String, flags: Int) extends Entity { } object NoSymbol extends Symbol("<nosymbol>", 0) { - override def fix(tpe: Type, owner: Symbol): Unit = {} + override def fix(tpe: Type, owner: Symbol): Unit = {} } class TypeSymbol(name: String, flags: Int) extends Symbol(name, flags) { @@ -113,7 +121,7 @@ class ClassSymbol(name: String, flags: Int) extends Symbol(name, flags) { class ValSymbol(name: String, flags: Int) extends Symbol(name, flags) { var clazz: Symbol = NoSymbol; - override def fix(sym: Symbol): Unit = { + override def fix(sym: Symbol): Unit = { clazz = sym; } } diff --git a/sources/scala/tools/scalap/EntityTable.scala b/sources/scala/tools/scalap/EntityTable.scala index 77a7decf84..b686613e2a 100644 --- a/sources/scala/tools/scalap/EntityTable.scala +++ b/sources/scala/tools/scalap/EntityTable.scala @@ -1,3 +1,11 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; import scala.collection.mutable._; @@ -10,127 +18,127 @@ class EntityTable(attrib: ScalaAttribute) { var root: Buffer[Symbol] = new Buffer; { - //Console.println("created table"); - var i = 0; + //Console.println("created table"); + var i = 0; while (i < attrib.table.length) { - table(i) = attrib.table(i) match { - case TermName(str) => Text(Names.decode(str)); - case TypeName(str) => Text(Names.decode(str)); - case _ => null; - } + table(i) = attrib.table(i) match { + case TermName(str) => Text(Names.decode(str)); + case TypeName(str) => Text(Names.decode(str)); + case _ => null; + } i = i + 1; } //Console.println("decoded names"); i = 0; var fixupIds: List[Int] = Nil; - while (i < attrib.table.length) { - table(i) = attrib.table(i) match { - case NoneSym() => - NoSymbol - case TypeSym(SymbolInfo(nameId, _, flags, _), _) => - fixupIds = i :: fixupIds; - new TypeSymbol(getText(nameId), flags) - case AliasSym(SymbolInfo(nameId, _, flags, _), _) => - fixupIds = i :: fixupIds; - new AliasSymbol(getText(nameId), flags) - case ClassSym(SymbolInfo(nameId, _, flags, _), _, _) => - fixupIds = i :: fixupIds; - new ClassSymbol(getText(nameId), flags) - case ValSym(SymbolInfo(nameId, _, flags, _), _) => - fixupIds = i :: fixupIds; - new ValSymbol(getText(nameId), flags) - case ExtRef(mod, nameId, _) => - fixupIds = i :: fixupIds; - new ExternalSymbol(getText(nameId), mod) - case _ => - table(i) - } + while (i < attrib.table.length) { + table(i) = attrib.table(i) match { + case NoneSym() => + NoSymbol + case TypeSym(SymbolInfo(nameId, _, flags, _), _) => + fixupIds = i :: fixupIds; + new TypeSymbol(getText(nameId), flags) + case AliasSym(SymbolInfo(nameId, _, flags, _), _) => + fixupIds = i :: fixupIds; + new AliasSymbol(getText(nameId), flags) + case ClassSym(SymbolInfo(nameId, _, flags, _), _, _) => + fixupIds = i :: fixupIds; + new ClassSymbol(getText(nameId), flags) + case ValSym(SymbolInfo(nameId, _, flags, _), _) => + fixupIds = i :: fixupIds; + new ValSymbol(getText(nameId), flags) + case ExtRef(mod, nameId, _) => + fixupIds = i :: fixupIds; + new ExternalSymbol(getText(nameId), mod) + case _ => + table(i) + } i = i + 1; } //Console.println("created symbols"); i = 0; while (i < attrib.table.length) { - val x = getType(i); + val x = getType(i); i = i + 1; } //Console.println("created types"); def fix(i: Int, info: SymbolInfo): Symbol = { - val sym = getSymbol(i); - sym.fix(getType(info.info), getSymbol(info.owner)); - sym + val sym = getSymbol(i); + sym.fix(getType(info.info), getSymbol(info.owner)); + sym } fixupIds foreach { - i => attrib.table(i) match { - case TypeSym(info, loId) => - fix(i, info).fix(getType(loId)); - case AliasSym(info, constrId) => - fix(i, info).fix(getSymbol(constrId)); - case ClassSym(info, typeId, constrId) => - val sym = fix(i, info); - sym.fix(getType(typeId)); - sym.fix(getSymbol(constrId)); - sym.owner match { - case x: ExternalSymbol => root += sym; - case _ => - } - case ValSym(info, classId) => - fix(i, info).fix(getSymbol(classId)); - case ExtRef(_, _, ownerId) => - getSymbol(i).fix(getSymbol(ownerId)); - } + i => attrib.table(i) match { + case TypeSym(info, loId) => + fix(i, info).fix(getType(loId)); + case AliasSym(info, constrId) => + fix(i, info).fix(getSymbol(constrId)); + case ClassSym(info, typeId, constrId) => + val sym = fix(i, info); + sym.fix(getType(typeId)); + sym.fix(getSymbol(constrId)); + sym.owner match { + case x: ExternalSymbol => root += sym; + case _ => + } + case ValSym(info, classId) => + fix(i, info).fix(getSymbol(classId)); + case ExtRef(_, _, ownerId) => + getSymbol(i).fix(getSymbol(ownerId)); + } } } def getText(i: Int): String = table(i) match { - case Text(str) => str; - } + case Text(str) => str; + } def getSymbol(i: Int): Symbol = - if (i < 0) NoSymbol else table(i).asInstanceOf[Symbol]; + if (i < 0) NoSymbol else table(i).asInstanceOf[Symbol]; def getSymbols(is: List[Int]): List[Symbol] = is map {i => getSymbol(i)}; def getType(i: Int): Type = { - if (i < 0) - NoType - else if (table(i) != null) { - if (table(i).isInstanceOf[Type]) - table(i).asInstanceOf[Type] - else - NoType - } else { - val res: Type = attrib.table(i) match { - case NoneType() => - NoType - case SelfType(symId) => - ThisType(getSymbol(symId)) - case SingleType(typeId, symId) => - SingletonType(getType(typeId), getSymbol(symId)) - case TypeReference(typeId, symId, argIds) => - TypeRef(getType(typeId), getSymbol(symId), getTypes(argIds)) - case CompoundTypeRef(symId, typeIds) => - CompoundType(getSymbol(symId), getTypes(typeIds)) - case MethodTypeRef(restypeId, argtypeIds) => - MethodType(getTypes(argtypeIds), getType(restypeId)) - case PolyTypeRef(typeId, symIds) => - PolyType(getType(typeId), getSymbols(symIds)) - case OverloadedTypeRef(ids) => - val Pair(symIds, typeIds) = ids partition { - i => (table(i) != null) && table(i).isSymbol - } - OverloadedType(getSymbols(symIds), getTypes(typeIds)) - case FlaggedType(flags, typeId) => - TypeFlag(getType(typeId), flags) - } - table(i) = res; - res - } + if (i < 0) + NoType + else if (table(i) != null) { + if (table(i).isInstanceOf[Type]) + table(i).asInstanceOf[Type] + else + NoType + } else { + val res: Type = attrib.table(i) match { + case NoneType() => + NoType + case SelfType(symId) => + ThisType(getSymbol(symId)) + case SingleType(typeId, symId) => + SingletonType(getType(typeId), getSymbol(symId)) + case TypeReference(typeId, symId, argIds) => + TypeRef(getType(typeId), getSymbol(symId), getTypes(argIds)) + case CompoundTypeRef(symId, typeIds) => + CompoundType(getSymbol(symId), getTypes(typeIds)) + case MethodTypeRef(restypeId, argtypeIds) => + MethodType(getTypes(argtypeIds), getType(restypeId)) + case PolyTypeRef(typeId, symIds) => + PolyType(getType(typeId), getSymbols(symIds)) + case OverloadedTypeRef(ids) => + val Pair(symIds, typeIds) = ids partition { + i => (table(i) != null) && table(i).isSymbol + } + OverloadedType(getSymbols(symIds), getTypes(typeIds)) + case FlaggedType(flags, typeId) => + TypeFlag(getType(typeId), flags) + } + table(i) = res; + res + } } def getTypes(is: List[Int]): List[Type] = is map {i => getType(i)}; def print: Unit = { - Console.println("ROOT = " + root); + Console.println("ROOT = " + root); var i = 0; while (i < table.length) { Console.println("" + i + ": " + table(i).toSource); diff --git a/sources/scala/tools/scalap/FileCache.scala b/sources/scala/tools/scalap/FileCache.scala index 9021d0ab98..546aa684ee 100644 --- a/sources/scala/tools/scalap/FileCache.scala +++ b/sources/scala/tools/scalap/FileCache.scala @@ -1,5 +1,10 @@ -// FileCache -// 20-Mar-2002, Matthias Zenger +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ package scalap; @@ -13,10 +18,10 @@ class FileCache { /** table of all opened jar-files */ protected val opened: mutable.Map[String, AbstractFile] = - //new mutable.HashMap[String, AbstractFile]; - new mutable.JavaMapAdaptor(new java.util.HashMap()); + //new mutable.HashMap[String, AbstractFile]; + new mutable.JavaMapAdaptor(new java.util.HashMap()); - def open(name: String): AbstractFile = open(null, name); + def open(name: String): AbstractFile = open(null, name); /** open file 'name' in directory 'dirname'; 'name' is a path * relative to 'dirname'; 'dirname' might also refer to a .zip @@ -24,10 +29,10 @@ class FileCache { */ def open(dirname: String, name: String): AbstractFile = { if (dirname == null) - new PlainFile(new File(name)) + new PlainFile(new File(name)) else if (dirname.endsWith(".jar")) { - if (!opened.isDefinedAt(dirname)) - opened(dirname) = new JarArchive(new File(dirname)); + if (!opened.isDefinedAt(dirname)) + opened(dirname) = new JarArchive(new File(dirname)); if (name == null) opened(dirname) else opened(dirname).open(name) } else if (name == null) new PlainFile(new File(dirname)) diff --git a/sources/scala/tools/scalap/Flags.scala b/sources/scala/tools/scalap/Flags.scala index 004228340b..f58aacc356 100644 --- a/sources/scala/tools/scalap/Flags.scala +++ b/sources/scala/tools/scalap/Flags.scala @@ -1,5 +1,14 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; + object Flags { final val DEFERRED = 0x00000001; @@ -31,13 +40,13 @@ object Flags { final val LABEL = 0x00200000; // symbol is a label symbol final val STATIC = 0x00400000; // "static" inner classes (i.e. after class norm.) final val STABLE = 0x00800000; // functions that are assumed to be stable - // (typically, access methods for valdefs) + // (typically, access methods for valdefs) final val CAPTURED = 0x01000000; // variables is accessed from nested function. final val CASEACCESSOR = 0x02000000; // function is a case constructor final val ACCESSOR = 0x04000000; // function is an access function for a - // value or variable + // value or variable final val BRIDGE = 0x08000000; // function is a bridge method. final val INTERFACE = 0x10000000; // symbol is a Java interface @@ -54,59 +63,59 @@ object Flags { final val ACCESSFLAGS = PRIVATE | PROTECTED; final val VARIANCES = COVAR | CONTRAVAR; - def isDeferred(flags: Int): Boolean = (flags & DEFERRED) != 0; + def isDeferred(flags: Int): Boolean = (flags & DEFERRED) != 0; - def isAbstract(flags: Int): Boolean = (flags & ABSTRACT) != 0; + def isAbstract(flags: Int): Boolean = (flags & ABSTRACT) != 0; - def isFinal(flags: Int): Boolean = (flags & FINAL) != 0; + def isFinal(flags: Int): Boolean = (flags & FINAL) != 0; - def isPrivate(flags: Int): Boolean = (flags & PRIVATE) != 0; + def isPrivate(flags: Int): Boolean = (flags & PRIVATE) != 0; - def isProtected(flags: Int): Boolean = (flags & PROTECTED) != 0; + def isProtected(flags: Int): Boolean = (flags & PROTECTED) != 0; - def isSealed(flags: Int): Boolean = (flags & SEALED) != 0; + def isSealed(flags: Int): Boolean = (flags & SEALED) != 0; - def isOverride(flags: Int): Boolean = (flags & OVERRIDE) != 0; + def isOverride(flags: Int): Boolean = (flags & OVERRIDE) != 0; - def isCase(flags: Int): Boolean = (flags & CASE) != 0; + def isCase(flags: Int): Boolean = (flags & CASE) != 0; - def isCaseAccessor(flags: Int): Boolean = (flags & CASEACCESSOR) != 0; + def isCaseAccessor(flags: Int): Boolean = (flags & CASEACCESSOR) != 0; - def isInterface(flags: Int): Boolean = (flags & INTERFACE) != 0; + def isInterface(flags: Int): Boolean = (flags & INTERFACE) != 0; - def isTrait(flags: Int): Boolean = (flags & TRAIT) != 0; + def isTrait(flags: Int): Boolean = (flags & TRAIT) != 0; - def isObj(flags: Int): Boolean = (flags & OBJECT) != 0; + def isObj(flags: Int): Boolean = (flags & OBJECT) != 0; - def isDef(flags: Int): Boolean = (flags & DEF) != 0; + def isDef(flags: Int): Boolean = (flags & DEF) != 0; - def isObjClass(flags: Int): Boolean = (flags & OBJECT) != 0; + def isObjClass(flags: Int): Boolean = (flags & OBJECT) != 0; - def isStatic(flags: Int): Boolean = (flags & STATIC) != 0; + def isStatic(flags: Int): Boolean = (flags & STATIC) != 0; - def isJava(flags: Int): Boolean = (flags & JAVA) != 0; + def isJava(flags: Int): Boolean = (flags & JAVA) != 0; - def isNoVal(flags: Int): Boolean = (flags & PACKAGE) != 0; + def isNoVal(flags: Int): Boolean = (flags & PACKAGE) != 0; - def toString(flags: Int): String = { - val buffer = new StringBuffer(); - var x: StringBuffer = buffer; - if (isPrivate(flags)) - x = buffer.append("private "); - if (isProtected(flags)) - x = buffer.append("protected "); - if (isAbstract(flags) && !isTrait(flags)) - x = buffer.append("abstract "); - if (isFinal(flags) && !isObj(flags)) - x = buffer.append("final "); - if (isSealed(flags)) - x = buffer.append("sealed "); - if (isCase(flags)) - x = buffer.append("case "); - if (isDef(flags)) - x = buffer.append("def "); - if (isOverride(flags)) - x = buffer.append("override "); - buffer.toString() - } + def toString(flags: Int): String = { + val buffer = new StringBuffer(); + var x: StringBuffer = buffer; + if (isPrivate(flags)) + x = buffer.append("private "); + if (isProtected(flags)) + x = buffer.append("protected "); + if (isAbstract(flags) && !isTrait(flags)) + x = buffer.append("abstract "); + if (isFinal(flags) && !isObj(flags)) + x = buffer.append("final "); + if (isSealed(flags)) + x = buffer.append("sealed "); + if (isCase(flags)) + x = buffer.append("case "); + if (isDef(flags)) + x = buffer.append("def "); + if (isOverride(flags)) + x = buffer.append("override "); + buffer.toString() + } } diff --git a/sources/scala/tools/scalap/Main.scala b/sources/scala/tools/scalap/Main.scala index bd44bfb732..052df7f83d 100644 --- a/sources/scala/tools/scalap/Main.scala +++ b/sources/scala/tools/scalap/Main.scala @@ -1,5 +1,10 @@ -// ClassPath -// 04-Mar-2002, Matthias Zenger +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ package scalap; @@ -9,38 +14,38 @@ import scala.collection._; object Main { - def usage: Unit = { - Console.println("usage: scalap <name>"); - } + def usage: Unit = { + Console.println("usage: scalap <name>"); + } - def main(args: Array[String]) = { - if (args.length == 0) - usage; - else { - val path = new ClassPath; - val file = path.openClass(Names.encode(args(0))); - if (file.exists) { - val reader = new ByteArrayReader(file.content); - val clazz = new Classfile(reader); - val attrib = clazz.attribs.find(a => a.toString() == "ScalaSignature"); - attrib match { - case Some(a) => - val info = new ScalaAttribute(a.reader); - //Console.println("read attribute"); - val symtab = new EntityTable(info); - //Console.println("read entities"); - //symtab.print; - val out = new OutputStreamWriter(System.out); - val writer = new ScalaWriter(out); - symtab.root.elements foreach ( - sym => { writer.printSymbol(sym); - writer.println*; }); - out.flush(); - case None => - Console.println("Java classes not supported yet."); - } - } else - Console.println("class/object not found."); - } - } + def main(args: Array[String]) = { + if (args.length == 0) + usage; + else { + val path = new ClassPath; + val file = path.openClass(Names.encode(args(0))); + if (file.exists) { + val reader = new ByteArrayReader(file.content); + val clazz = new Classfile(reader); + val attrib = clazz.attribs.find(a => a.toString() == "ScalaSignature"); + attrib match { + case Some(a) => + val info = new ScalaAttribute(a.reader); + //Console.println("read attribute"); + val symtab = new EntityTable(info); + //Console.println("read entities"); + //symtab.print; + val out = new OutputStreamWriter(System.out); + val writer = new ScalaWriter(out); + symtab.root.elements foreach ( + sym => { writer.printSymbol(sym); + writer.println*; }); + out.flush(); + case None => + Console.println("Java classes not supported yet."); + } + } else + Console.println("class/object not found."); + } + } } diff --git a/sources/scala/tools/scalap/Names.scala b/sources/scala/tools/scalap/Names.scala index bc3d79eba1..7d03b8e4b5 100644 --- a/sources/scala/tools/scalap/Names.scala +++ b/sources/scala/tools/scalap/Names.scala @@ -1,42 +1,51 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; + object Names { - val operatorName = new Array[String](128); - operatorName('$') = "$"; + val operatorName = new Array[String](128); + operatorName('$') = "$"; operatorName('~') = "$tilde"; - operatorName('=') = "$eq"; - operatorName('<') = "$less"; - operatorName('>') = "$greater"; - operatorName('!') = "$bang"; - operatorName('#') = "$hash"; - operatorName('%') = "$percent"; - operatorName('^') = "$up"; - operatorName('&') = "$amp"; - operatorName('|') = "$bar"; - operatorName('*') = "$times"; - operatorName('/') = "$div"; - operatorName('+') = "$plus"; - operatorName('-') = "$minus"; - operatorName(':') = "$colon"; + operatorName('=') = "$eq"; + operatorName('<') = "$less"; + operatorName('>') = "$greater"; + operatorName('!') = "$bang"; + operatorName('#') = "$hash"; + operatorName('%') = "$percent"; + operatorName('^') = "$up"; + operatorName('&') = "$amp"; + operatorName('|') = "$bar"; + operatorName('*') = "$times"; + operatorName('/') = "$div"; + operatorName('+') = "$plus"; + operatorName('-') = "$minus"; + operatorName(':') = "$colon"; /** Replace operator symbols by corresponding "$op_name" in names. */ def encode(name: String): String = { - var i = 0; - val len = name.length(); - val res = new StringBuffer(); - while (i < len) { - val c = name.charAt(i); - if (c < 128) { - val nop = operatorName(c); - if (nop == null) - res.append(c); - else - res.append(nop); - } else - res.append(c); - i = i + 1; + var i = 0; + val len = name.length(); + val res = new StringBuffer(); + while (i < len) { + val c = name.charAt(i); + if (c < 128) { + val nop = operatorName(c); + if (nop == null) + res.append(c); + else + res.append(nop); + } else + res.append(c); + i = i + 1; } res.toString() } @@ -45,41 +54,41 @@ object Names { */ def decode(name: String): String = { var i = 0; - val len = name.length(); - val res = new StringBuffer(); - while (i < len) { - val c = name.charAt(i); - if (c == '$') { - var j = len; - while (j > i) { - val prefix = name.substring(i, j); - val c = lookup(prefix); - if (c != null) { - i = j; - res.append(c); - } else - j = j - 1; - } - } else { - i = i + 1; - res.append(c); - } - } - res.toString() + val len = name.length(); + val res = new StringBuffer(); + while (i < len) { + val c = name.charAt(i); + if (c == '$') { + var j = len; + while (j > i) { + val prefix = name.substring(i, j); + val c = lookup(prefix); + if (c != null) { + i = j; + res.append(c); + } else + j = j - 1; + } + } else { + i = i + 1; + res.append(c); + } + } + res.toString() } /** Looks up the array entry for the operator name. */ def lookup(string: String): String = { - var i = 0; - var res: String = null; - while (i < 128) { - if (string.equals(operatorName(i))) { - res = String.valueOf(i.asInstanceOf[Char]); - i = 128; - } - i = i + 1; - } - res + var i = 0; + var res: String = null; + while (i < 128) { + if (string.equals(operatorName(i))) { + res = String.valueOf(i.asInstanceOf[Char]); + i = 128; + } + i = i + 1; + } + res } } diff --git a/sources/scala/tools/scalap/ScalaAttribute.scala b/sources/scala/tools/scalap/ScalaAttribute.scala index f4aa413b52..6c2860117f 100644 --- a/sources/scala/tools/scalap/ScalaAttribute.scala +++ b/sources/scala/tools/scalap/ScalaAttribute.scala @@ -1,3 +1,11 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; import scala.collection.mutable._; @@ -5,91 +13,91 @@ import scala.collection.mutable._; class ScalaAttribute(in: ByteArrayReader) { - val table = readTable; + val table = readTable; - def readTable: Array[AttribEntry] = { - val res = new Array[AttribEntry](in.nextNat); - var i = 0; - while (i < res.length) { - res(i) = readTableEntry; - i = i + 1; - } - res - } + def readTable: Array[AttribEntry] = { + val res = new Array[AttribEntry](in.nextNat); + var i = 0; + while (i < res.length) { + res(i) = readTableEntry; + i = i + 1; + } + res + } - def readTableEntry: AttribEntry = { - val tag = in.nextByte; - val len = in.nextNat; - //Console.println("" + tag + ": " + len); - val end = in.bp + len; - tag match { - case 1 /* TERMname */ => - TermName(in.nextUTF8(len)) - case 2 /* TYPEname */ => - TypeName(in.nextUTF8(len)) - case 3 /* NONEsym */ => - NoneSym() - case 4 /* TYPEsym */ => - TypeSym(readSymInfo, in.nextNat) - case 5 /* ALIASsym */ => - AliasSym(readSymInfo, in.nextNat) - case 6 /* CLASSsym */ => - ClassSym(readSymInfo, in.nextNat, in.nextNat) - case 7 /* VALsym */ => - ValSym(readSymInfo, if (in.bp < end) in.nextNat else -1) - case 8 /* EXTref */ => - ExtRef(false, in.nextNat, if (in.bp < end) in.nextNat else -1) - case 9 /* EXTMODCLASSref */ => - ExtRef(true, in.nextNat, if (in.bp < end) in.nextNat else -1) - case 10 /* NOtpe */ => - NoneType() - case 11 /* THIStpe */ => - SelfType(in.nextNat) - case 12 /* SINGLEtpe */ => - SingleType(in.nextNat, in.nextNat) - case 13 /* TYPEREFtpe */ => - TypeReference(in.nextNat, in.nextNat, readRefs(end)) - case 14 /* COMPOUNDtpe */ => - CompoundTypeRef(in.nextNat, readRefs(end)) - case 15 /* METHODtpe */ => - MethodTypeRef(in.nextNat, readRefs(end)) - case 16 /* POLYtpe */ => - PolyTypeRef(in.nextNat, readRefs(end)) - case 17 /* OVERLOADEDtpe */ => - OverloadedTypeRef(readRefs(end)) - case 20 /* FLAGGEDtpe */ => - FlaggedType(in.nextNat, in.nextNat) - } - } + def readTableEntry: AttribEntry = { + val tag = in.nextByte; + val len = in.nextNat; + //Console.println("" + tag + ": " + len); + val end = in.bp + len; + tag match { + case 1 /* TERMname */ => + TermName(in.nextUTF8(len)) + case 2 /* TYPEname */ => + TypeName(in.nextUTF8(len)) + case 3 /* NONEsym */ => + NoneSym() + case 4 /* TYPEsym */ => + TypeSym(readSymInfo, in.nextNat) + case 5 /* ALIASsym */ => + AliasSym(readSymInfo, in.nextNat) + case 6 /* CLASSsym */ => + ClassSym(readSymInfo, in.nextNat, in.nextNat) + case 7 /* VALsym */ => + ValSym(readSymInfo, if (in.bp < end) in.nextNat else -1) + case 8 /* EXTref */ => + ExtRef(false, in.nextNat, if (in.bp < end) in.nextNat else -1) + case 9 /* EXTMODCLASSref */ => + ExtRef(true, in.nextNat, if (in.bp < end) in.nextNat else -1) + case 10 /* NOtpe */ => + NoneType() + case 11 /* THIStpe */ => + SelfType(in.nextNat) + case 12 /* SINGLEtpe */ => + SingleType(in.nextNat, in.nextNat) + case 13 /* TYPEREFtpe */ => + TypeReference(in.nextNat, in.nextNat, readRefs(end)) + case 14 /* COMPOUNDtpe */ => + CompoundTypeRef(in.nextNat, readRefs(end)) + case 15 /* METHODtpe */ => + MethodTypeRef(in.nextNat, readRefs(end)) + case 16 /* POLYtpe */ => + PolyTypeRef(in.nextNat, readRefs(end)) + case 17 /* OVERLOADEDtpe */ => + OverloadedTypeRef(readRefs(end)) + case 20 /* FLAGGEDtpe */ => + FlaggedType(in.nextNat, in.nextNat) + } + } - def readSymInfo: SymbolInfo = - SymbolInfo(in.nextNat, in.nextNat, in.nextNat, in.nextNat); + def readSymInfo: SymbolInfo = + SymbolInfo(in.nextNat, in.nextNat, in.nextNat, in.nextNat); - def readRefs(end: Int): List[Int] = { - var res = new Buffer[Int]; - while (in.bp < end) - res += in.nextNat; - res.toList - } + def readRefs(end: Int): List[Int] = { + var res = new Buffer[Int]; + while (in.bp < end) + res += in.nextNat; + res.toList + } - class AttribEntry; - case class TermName(name: String) extends AttribEntry; - case class TypeName(name: String) extends AttribEntry; - case class NoneSym() extends AttribEntry; - case class TypeSym(info: SymbolInfo, lobound: Int) extends AttribEntry; - case class AliasSym(info: SymbolInfo, constr: Int) extends AttribEntry; - case class ClassSym(info: SymbolInfo, thistpe: Int, constr: Int) extends AttribEntry; - case class ValSym(info: SymbolInfo, classsym: Int) extends AttribEntry; - case class ExtRef(mod: Boolean, name: Int, owner: Int) extends AttribEntry; - case class NoneType() extends AttribEntry; - case class SelfType(sym: Int) extends AttribEntry; - case class SingleType(typeref: Int, sym: Int) extends AttribEntry; - case class TypeReference(typeref: Int, sym: Int, args: List[Int]) extends AttribEntry; - case class CompoundTypeRef(sym: Int, components: List[Int]) extends AttribEntry; - case class MethodTypeRef(res: Int, args: List[Int]) extends AttribEntry; - case class PolyTypeRef(tpe: Int, sym: List[Int]) extends AttribEntry; - case class OverloadedTypeRef(symandtpe: List[Int]) extends AttribEntry; - case class FlaggedType(flags: Int, tpe: Int) extends AttribEntry; + class AttribEntry; + case class TermName(name: String) extends AttribEntry; + case class TypeName(name: String) extends AttribEntry; + case class NoneSym() extends AttribEntry; + case class TypeSym(info: SymbolInfo, lobound: Int) extends AttribEntry; + case class AliasSym(info: SymbolInfo, constr: Int) extends AttribEntry; + case class ClassSym(info: SymbolInfo, thistpe: Int, constr: Int) extends AttribEntry; + case class ValSym(info: SymbolInfo, classsym: Int) extends AttribEntry; + case class ExtRef(mod: Boolean, name: Int, owner: Int) extends AttribEntry; + case class NoneType() extends AttribEntry; + case class SelfType(sym: Int) extends AttribEntry; + case class SingleType(typeref: Int, sym: Int) extends AttribEntry; + case class TypeReference(typeref: Int, sym: Int, args: List[Int]) extends AttribEntry; + case class CompoundTypeRef(sym: Int, components: List[Int]) extends AttribEntry; + case class MethodTypeRef(res: Int, args: List[Int]) extends AttribEntry; + case class PolyTypeRef(tpe: Int, sym: List[Int]) extends AttribEntry; + case class OverloadedTypeRef(symandtpe: List[Int]) extends AttribEntry; + case class FlaggedType(flags: Int, tpe: Int) extends AttribEntry; - case class SymbolInfo(name: Int, owner: Int, flags: Int, info: Int); + case class SymbolInfo(name: Int, owner: Int, flags: Int, info: Int); } diff --git a/sources/scala/tools/scalap/ScalaWriter.scala b/sources/scala/tools/scalap/ScalaWriter.scala index c829abb892..f36a1fe29b 100644 --- a/sources/scala/tools/scalap/ScalaWriter.scala +++ b/sources/scala/tools/scalap/ScalaWriter.scala @@ -1,3 +1,11 @@ +/* ___ ____ ___ __ ___ ___ +** / _// __// _ | / / / _ | / _ \ Scala classfile decoder +** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL +** /____/\___/_/ |_/____/_/ |_/_/ +** +** $Id$ +*/ + package scalap; import java.io._; @@ -7,212 +15,212 @@ import scala.collection.mutable._; class ScalaWriter(writer: Writer) extends CodeWriter(writer) { def printFlags(flags: Int): Unit = { - val buffer = new StringBuffer(); - var x: StringBuffer = buffer; - if (Flags.isPrivate(flags)) - x = buffer.append("private "); - if (Flags.isProtected(flags)) - x = buffer.append("protected "); - if (Flags.isAbstract(flags) && !Flags.isTrait(flags)) - x = buffer.append("abstract "); - if (Flags.isFinal(flags) && !Flags.isObj(flags)) - x = buffer.append("final "); - if (Flags.isSealed(flags)) - x = buffer.append("sealed "); - if (Flags.isCase(flags)) - x = buffer.append("case "); - if (Flags.isDef(flags)) - x = buffer.append("def "); - if (Flags.isOverride(flags)) - x = buffer.append("override "); - print(buffer.toString())* + val buffer = new StringBuffer(); + var x: StringBuffer = buffer; + if (Flags.isPrivate(flags)) + x = buffer.append("private "); + if (Flags.isProtected(flags)) + x = buffer.append("protected "); + if (Flags.isAbstract(flags) && !Flags.isTrait(flags)) + x = buffer.append("abstract "); + if (Flags.isFinal(flags) && !Flags.isObj(flags)) + x = buffer.append("final "); + if (Flags.isSealed(flags)) + x = buffer.append("sealed "); + if (Flags.isCase(flags)) + x = buffer.append("case "); + if (Flags.isDef(flags)) + x = buffer.append("def "); + if (Flags.isOverride(flags)) + x = buffer.append("override "); + print(buffer.toString())* } def printType(tpe: Type): Unit = { - printType0(tpe); - tpe match { - case ThisType(_) => print(".type")* - case SingletonType(_, _) => print(".type")* - case _ => - } + printType0(tpe); + tpe match { + case ThisType(_) => print(".type")* + case SingletonType(_, _) => print(".type")* + case _ => + } } - def printTypes(tpes: List[Type], begin: String, infix: String, end: String): Unit = { - if (!tpes.isEmpty) - printTypes0(tpes, begin, infix, end); - } + def printTypes(tpes: List[Type], begin: String, infix: String, end: String): Unit = { + if (!tpes.isEmpty) + printTypes0(tpes, begin, infix, end); + } - def printTypes0(tpes: List[Type], begin: String, infix: String, end: String): Unit = { - print(begin)*; - if (!tpes.isEmpty) { - printType(tpes.head); - tpes.tail foreach (t => { print(infix)*; printType(t) }); - } - print(end)*; - } + def printTypes0(tpes: List[Type], begin: String, infix: String, end: String): Unit = { + print(begin)*; + if (!tpes.isEmpty) { + printType(tpes.head); + tpes.tail foreach (t => { print(infix)*; printType(t) }); + } + print(end)*; + } - def printType0(tpe: Type): Unit = tpe match { - case NoType => - case ThisType(sym) => sym match { - case x: ExternalSymbol => print(sym.fullname)* - case NoSymbol => print("this")* - case _ => print(sym.fullname).print(".this")* - } - case SingletonType(tpe, sym) => - printPrefix(tpe); - print(sym.name)* - case TypeRef(tpe, sym, args) => - printPrefix(tpe); - print(sym.name)*; - printTypes(args, "[", ", ", "]"); - case CompoundType(clazz, components) => - printTypes(components, "", " with ", ""); - if (clazz != NoSymbol) - printScope(clazz.members); - case MethodType(_, _) => - var tpe0 = tpe; - while (tpe0.isInstanceOf[MethodType]) { - tpe0 match { - case MethodType(argtpes, restpe) => - printTypes0(argtpes, "(", ", ", ")"); - tpe0 = restpe; - } - } - print(":").newspace*; - printType(tpe0); - case PolyType(tpe, tvars) => - print("[")*; - if (!tvars.isEmpty) { - printTVar(tvars.head); - tvars.tail foreach (sym => {print(", ")*; printTVar(sym);}); - } - print("]")*; - printType(tpe); - case OverloadedType(_, tpes) => - printTypes(tpes, "", " <and> ", ""); - case TypeFlag(TypeRef(_, _, List(tpe0)), flags) => - if ((flags & 8) != 0) - print("def ")*; - printType(tpe0); - if ((flags & 4) != 0) - print("*")*; - case TypeFlag(tpe0, flags) => - if ((flags & 8) != 0) - print("def ")*; - printType(tpe0); - case _ => print("<unknown type>")*; - } + def printType0(tpe: Type): Unit = tpe match { + case NoType => + case ThisType(sym) => sym match { + case x: ExternalSymbol => print(sym.fullname)* + case NoSymbol => print("this")* + case _ => print(sym.fullname).print(".this")* + } + case SingletonType(tpe, sym) => + printPrefix(tpe); + print(sym.name)* + case TypeRef(tpe, sym, args) => + printPrefix(tpe); + print(sym.name)*; + printTypes(args, "[", ", ", "]"); + case CompoundType(clazz, components) => + printTypes(components, "", " with ", ""); + if (clazz != NoSymbol) + printScope(clazz.members); + case MethodType(_, _) => + var tpe0 = tpe; + while (tpe0.isInstanceOf[MethodType]) { + tpe0 match { + case MethodType(argtpes, restpe) => + printTypes0(argtpes, "(", ", ", ")"); + tpe0 = restpe; + } + } + print(":").newspace*; + printType(tpe0); + case PolyType(tpe, tvars) => + print("[")*; + if (!tvars.isEmpty) { + printTVar(tvars.head); + tvars.tail foreach (sym => {print(", ")*; printTVar(sym);}); + } + print("]")*; + printType(tpe); + case OverloadedType(_, tpes) => + printTypes(tpes, "", " <and> ", ""); + case TypeFlag(TypeRef(_, _, List(tpe0)), flags) => + if ((flags & 8) != 0) + print("def ")*; + printType(tpe0); + if ((flags & 4) != 0) + print("*")*; + case TypeFlag(tpe0, flags) => + if ((flags & 8) != 0) + print("def ")*; + printType(tpe0); + case _ => print("<unknown type>")*; + } - def printPrefix(tpe: Type): Unit = tpe match { - case NoType => - case ThisType(NoSymbol) => - case ThisType(sym) => - if (sym.name.length() != 0) { - printType0(tpe); - print(".")* - } - case TypeRef(_, _, _) => - printType0(tpe); - print("#")* - case _ => - printType0(tpe); - print(".")* - } + def printPrefix(tpe: Type): Unit = tpe match { + case NoType => + case ThisType(NoSymbol) => + case ThisType(sym) => + if (sym.name.length() != 0) { + printType0(tpe); + print(".")* + } + case TypeRef(_, _, _) => + printType0(tpe); + print("#")* + case _ => + printType0(tpe); + print(".")* + } - def printTVar(tvar: Symbol): Unit = tvar match { - case sym: TypeSymbol => print(sym.name); - if (!isExternalType(sym.tpe, "Any")) { - print(" <: ")*; - printType(sym.tpe); - } - if (!isExternalType(sym.lower, "All")) { - print(" >: ")*; - printType(sym.lower); - } - } + def printTVar(tvar: Symbol): Unit = tvar match { + case sym: TypeSymbol => print(sym.name); + if (!isExternalType(sym.tpe, "Any")) { + print(" <: ")*; + printType(sym.tpe); + } + if (!isExternalType(sym.lower, "All")) { + print(" >: ")*; + printType(sym.lower); + } + } - def isExternalType(tpe: Type, name: String): Boolean = tpe match { - case TypeRef(SingletonType(ThisType(root), pck), sym, Nil) => - (root.name.length() == 0) && - pck.name.equals("scala") && - sym.name.equals(name) - case _ => false - } + def isExternalType(tpe: Type, name: String): Boolean = tpe match { + case TypeRef(SingletonType(ThisType(root), pck), sym, Nil) => + (root.name.length() == 0) && + pck.name.equals("scala") && + sym.name.equals(name) + case _ => false + } - def printSymbol(sym: Symbol): Unit = sym match { - case NoSymbol => - print("<nosymbol>")* - case s: TypeSymbol => - print(Flags.toString(s.flags))*; - print("type ")*; - printTVar(s); - case s: AliasSymbol => - print(Flags.toString(s.flags))*; - print("type " + s.name + " = ")*; - printType(s.tpe); - case s: ClassSymbol => - print(Flags.toString(s.flags))*; - if (Flags.isDeferred(s.flags)) - print("/*deferred*/ ")*; - if (Flags.isObj(s.flags)) - print("object " + s.name); - else if (Flags.isTrait(s.flags)) - print("trait " + s.name)*; - else - print("class " + s.name)*; - printConstr(s.constr); - print(" extends "); - printType(s.tpe); - case s: ValSymbol => - s.tpe match { - case PolyType(tpe, Nil) => - print("def " + s.name + ": ")*; - printType(tpe); - case PolyType(_, _) => - print("def " + s.name)*; - printType(s.tpe); - case MethodType(_, _) => - print("def " + s.name)*; - printType(s.tpe); - case _ => - print("val " + s.name + ": ")*; - printType(s.tpe); - } - case s: ExternalSymbol => - print("<externalsymbol: " + s.fullname + ">")* - } + def printSymbol(sym: Symbol): Unit = sym match { + case NoSymbol => + print("<nosymbol>")* + case s: TypeSymbol => + print(Flags.toString(s.flags))*; + print("type ")*; + printTVar(s); + case s: AliasSymbol => + print(Flags.toString(s.flags))*; + print("type " + s.name + " = ")*; + printType(s.tpe); + case s: ClassSymbol => + print(Flags.toString(s.flags))*; + if (Flags.isDeferred(s.flags)) + print("/*deferred*/ ")*; + if (Flags.isObj(s.flags)) + print("object " + s.name); + else if (Flags.isTrait(s.flags)) + print("trait " + s.name)*; + else + print("class " + s.name)*; + printConstr(s.constr); + print(" extends "); + printType(s.tpe); + case s: ValSymbol => + s.tpe match { + case PolyType(tpe, Nil) => + print("def " + s.name + ": ")*; + printType(tpe); + case PolyType(_, _) => + print("def " + s.name)*; + printType(s.tpe); + case MethodType(_, _) => + print("def " + s.name)*; + printType(s.tpe); + case _ => + print("val " + s.name + ": ")*; + printType(s.tpe); + } + case s: ExternalSymbol => + print("<externalsymbol: " + s.fullname + ">")* + } - def printConstr(sym: Symbol): Unit = sym match { - case s: ValSymbol => - s.tpe match { - case PolyType(MethodType(argtpes, _), tvars) => - print("[")*; - if (!tvars.isEmpty) { - printTVar(tvars.head); - tvars.tail foreach (sym => {print(", ")*; printTVar(sym);}); - } - print("]")*; - printTypes(argtpes, "(", ", ", ")"); - case MethodType(argtpes, _) => - printTypes(argtpes, "(", ", ", ")"); - case _ => - } - } + def printConstr(sym: Symbol): Unit = sym match { + case s: ValSymbol => + s.tpe match { + case PolyType(MethodType(argtpes, _), tvars) => + print("[")*; + if (!tvars.isEmpty) { + printTVar(tvars.head); + tvars.tail foreach (sym => {print(", ")*; printTVar(sym);}); + } + print("]")*; + printTypes(argtpes, "(", ", ", ")"); + case MethodType(argtpes, _) => + printTypes(argtpes, "(", ", ", ")"); + case _ => + } + } def printScope(scope: Buffer[Symbol]): Unit = { var first = true; scope.elements foreach ( - sym => { sym match { - case s: ValSymbol if - (s.tpe.isInstanceOf[OverloadedType] || - (Flags.isCaseAccessor(s.flags) && - !s.tpe.isInstanceOf[PolyType])) => - case _ => - if (first) print(" {").indent* else print(";")*; - first = false; - newline*; - printSymbol(sym); - }}); + sym => { sym match { + case s: ValSymbol if + (s.tpe.isInstanceOf[OverloadedType] || + (Flags.isCaseAccessor(s.flags) && + !s.tpe.isInstanceOf[PolyType])) => + case _ => + if (first) print(" {").indent* else print(";")*; + first = false; + newline*; + printSymbol(sym); + }}); if (!first) newline.undent.print("}")* } |