summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMatthias Zenger <mzenger@gmail.com>2003-11-16 15:21:25 +0000
committerMatthias Zenger <mzenger@gmail.com>2003-11-16 15:21:25 +0000
commit02e19018945c1ba25574192c0d968c6e2978e6e2 (patch)
tree1feba8dc840b92f4f81081d335fc1ef6067deace /sources
parentb9035ad31a97b94eb95a549c125281f1c357699c (diff)
downloadscala-02e19018945c1ba25574192c0d968c6e2978e6e2.tar.gz
scala-02e19018945c1ba25574192c0d968c6e2978e6e2.tar.bz2
scala-02e19018945c1ba25574192c0d968c6e2978e6e2.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/scalap/JavaWriter.scala168
1 files changed, 168 insertions, 0 deletions
diff --git a/sources/scala/tools/scalap/JavaWriter.scala b/sources/scala/tools/scalap/JavaWriter.scala
new file mode 100644
index 0000000000..9ba45aefea
--- /dev/null
+++ b/sources/scala/tools/scalap/JavaWriter.scala
@@ -0,0 +1,168 @@
+/* ___ ____ ___ __ ___ ___
+** / _// __// _ | / / / _ | / _ \ Scala classfile decoder
+** __\ \/ /__/ __ |/ /__/ __ |/ ___/ (c) 2003, LAMP/EPFL
+** /____/\___/_/ |_/____/_/ |_/_/
+**
+** $Id$
+*/
+
+package scala.tools.scalap;
+
+import java.io._;
+
+
+class JavaWriter(classfile: Classfile, writer: Writer) extends CodeWriter(writer) {
+
+ val cf = classfile;
+
+ def flagsToStr(clazz: Boolean, flags: Int) = {
+ val buffer = new StringBuffer();
+ var x: StringBuffer = buffer;
+ if (((flags & 0x0007) == 0) &&
+ ((flags & 0x0002) != 0))
+ x = buffer.append("private ");
+ if ((flags & 0x0004) != 0)
+ x = buffer.append("protected ");
+ if ((flags & 0x0010) != 0)
+ x = buffer.append("final ");
+ if ((flags & 0x0400) != 0)
+ x = if (clazz) buffer.append("abstract ")
+ else buffer.append("/*deferred*/ ");
+ buffer.toString()
+ }
+
+ def nameToClass(str: String) = {
+ val res = Names.decode(str.replace('/', '.'));
+ if (res == "java.lang.Object") "scala.AnyRef" else res
+ }
+
+ def nameToSimpleClass(str: String) =
+ Names.decode(str.substring(str.lastIndexOf('/') + 1));
+
+ def nameToPackage(str: String) =
+ Names.decode(str.substring(0, str.lastIndexOf('/')).replace('/', '.'));
+
+ def sigToType(str: String): String =
+ sigToType(str, 0)._1;
+
+ def sigToType(str: String, i: Int): Pair[String, Int] = str.charAt(i) match {
+ case 'B' => Pair("scala.Byte", i + 1)
+ case 'C' => Pair("scala.Char", i + 1)
+ case 'D' => Pair("scala.Double", i + 1)
+ case 'F' => Pair("scala.Float", i + 1)
+ case 'I' => Pair("scala.Int", i + 1)
+ case 'J' => Pair("scala.Long", i + 1)
+ case 'S' => Pair("scala.Short", i + 1)
+ case 'V' => Pair("scala.Unit", i + 1)
+ case 'Z' => Pair("scala.Boolean", i + 1)
+ case 'L' => val j = str.indexOf(';', i);
+ Pair(nameToClass(str.substring(i + 1, j)), j + 1)
+ case '[' => val Pair(tpe, j) = sigToType(str, i + 1);
+ Pair("scala.Array[" + tpe + "]", j)
+ case '(' => val Pair(tpe, j) = sigToType0(str, i + 1);
+ Pair("(" + tpe, j)
+ case ')' => val Pair(tpe, j) = sigToType(str, i + 1);
+ Pair("): " + tpe, j)
+ }
+
+ def sigToType0(str: String, i: Int): Pair[String, Int] =
+ if (str.charAt(i) == ')')
+ sigToType(str, i)
+ else {
+ val Pair(tpe, j) = sigToType(str, i);
+ if (str.charAt(j) == ')') {
+ val Pair(rest, k) = sigToType(str, j);
+ Pair(tpe + rest, k)
+ } else {
+ val Pair(rest, k) = sigToType0(str, j);
+ Pair(tpe + ", " + rest, k)
+ }
+ };
+
+ def getName(n: Int): String = cf.pool(n) match {
+ case cf.UTF8(str) => str;
+ case cf.StringConst(m) => getName(m);
+ case cf.ClassRef(m) => getName(m);
+ case x => Console.println("* " + x); "<error>"
+ }
+
+ def getClassName(n: Int): String = nameToClass(getName(n));
+
+ def getSimpleClassName(n: Int): String = nameToSimpleClass(getName(n));
+
+ def getPackage(n: Int): String = nameToPackage(getName(n));
+
+ def getType(n: Int): String = sigToType(getName(n));
+
+ def isStatic(flags: Int) = (flags & 0x0008) != 0;
+
+ def isInterface(flags: Int) = (flags & 0x0200) != 0;
+
+ def isConstr(name: String) = (name == "<init>");
+
+ def printField(flags: Int, name: Int, tpe: Int, attribs: List[cf.Attribute]) = {
+ print(flagsToStr(false, flags))*;
+ if ((flags & 0x0010) != 0)
+ print("val " + Names.decode(getName(name)))*;
+ else
+ print("final var " + Names.decode(getName(name)))*;
+ print(": " + getType(tpe) + ";").newline*;
+ }
+
+ def printMethod(flags: Int, name: Int, tpe: Int, attribs: List[cf.Attribute]) = {
+ if (getName(name) == "<init>")
+ print(flagsToStr(false, flags))*;
+ if (getName(name) == "<init>") {
+ print("def this" + getType(tpe) + ";").newline*;
+ } else {
+ print("def " + Names.decode(getName(name)))*;
+ print(getType(tpe) + ";").newline*;
+ }
+ }
+
+ def printClass = {
+ val pck = getPackage(cf.classname);
+ if (pck.length() > 0)
+ println("package " + pck + ";");
+ print(flagsToStr(true, cf.flags))*;
+ if (isInterface(cf.flags)) {
+ print("trait " + getSimpleClassName(cf.classname))*;
+ } else {
+ print("class " + getSimpleClassName(cf.classname))*;
+ if (cf.pool(cf.superclass) != null)
+ print(" extends " + getClassName(cf.superclass))*;
+ }
+ cf.interfaces foreach {
+ n => print(" with " + getClassName(n))*;
+ }
+ var statics: List[cf.Member] = Nil;
+ print(" {").indent.newline;
+ cf.fields foreach {
+ case m@cf.Member(_, flags, name, tpe, attribs) =>
+ if (isStatic(flags))
+ statics = m :: statics;
+ else
+ printField(flags, name, tpe, attribs)
+ }
+ cf.methods foreach {
+ case m@cf.Member(_, flags, name, tpe, attribs) =>
+ if (isStatic(flags))
+ statics = m :: statics;
+ else
+ printMethod(flags, name, tpe, attribs)
+ }
+ undent.print("}").newline*;
+ if (!statics.isEmpty) {
+ print("object " + getSimpleClassName(cf.classname) + " {")*;
+ indent.newline;
+ statics foreach {
+ case cf.Member(true, flags, name, tpe, attribs) =>
+ printField(flags, name, tpe, attribs)
+ case cf.Member(false, flags, name, tpe, attribs) =>
+ if (getName(name) != "<clinit>")
+ printMethod(flags, name, tpe, attribs)
+ }
+ undent.print("}").newline*
+ }
+ }
+}