summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
diff options
context:
space:
mode:
authormichelou <michelou@epfl.ch>2007-04-20 16:57:00 +0000
committermichelou <michelou@epfl.ch>2007-04-20 16:57:00 +0000
commit821fbc5a87af076b54aec9c3bf5703218711c9f9 (patch)
tree8c2e92f0c2f0276986c251dc514b46d331c4c155 /src/compiler/scala/tools/nsc/ast/NodePrinters.scala
parent96ac0066d7c69eec22be0afe6fb8f6b20e68b2e4 (diff)
downloadscala-821fbc5a87af076b54aec9c3bf5703218711c9f9.tar.gz
scala-821fbc5a87af076b54aec9c3bf5703218711c9f9.tar.bz2
scala-821fbc5a87af076b54aec9c3bf5703218711c9f9.zip
added Global.nodeToString
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/NodePrinters.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
new file mode 100644
index 0000000000..709f268b13
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -0,0 +1,244 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id: $
+
+package scala.tools.nsc.ast
+
+import compat.Platform.EOL
+import symtab.Flags._
+
+/** The object <code>nodePrinter</code> converts the internal tree
+ * representation to a string formatted as a Scala expression.
+ *
+ * @author Stephane Micheloud
+ * @version 1.0
+ */
+abstract class NodePrinters {
+
+ val global: Global
+ import global._
+
+ object InfoLevel extends Enumeration {
+ val Quiet, Normal, Verbose = Value
+ }
+ var infolevel = InfoLevel.Quiet
+
+ object nodeToString extends Function1[Tree, String] {
+ private val buf = new StringBuilder
+
+ def apply(tree: Tree): String = {
+ def traverse(tree: Tree, level: Int, comma: Boolean) {
+ def println(s: String) {
+ for (i <- 0 until level) buf.append(" ")
+ buf.append(s)
+ buf.append(EOL)
+ }
+ def printcln(s: String) {
+ for (i <- 0 until level) buf.append(" ")
+ buf.append(s)
+ if (comma) buf.append(",")
+ buf.append(EOL)
+ }
+ def annotationInfoToString(attr: AnnotationInfo[Constant]) = {
+ val str = new StringBuilder
+ str.append(attr.atp.toString())
+ if (!attr.args.isEmpty)
+ str.append(attr.args.mkString("(", ",", ")"))
+ if (!attr.assocs.isEmpty)
+ for (((name, value), index) <- attr.assocs.zipWithIndex) {
+ if (index > 0)
+ str.append(", ")
+ str.append(name).append(" = ").append(value)
+ }
+ str.toString
+ }
+ def symflags(tree: Tree): String = {
+ val sym = tree.symbol
+ val buf = new StringBuffer
+ if (sym hasFlag BRIDGE ) buf.append(" | BRIDGE")
+ if (sym hasFlag FINAL ) buf.append(" | FINAL")
+ if (sym hasFlag LOCAL ) buf.append(" | LOCAL")
+ if (sym hasFlag METHOD ) buf.append(" | METHOD")
+ if (sym hasFlag PARAMACCESSOR) buf.append(" | PARAMACCESSOR")
+ if (sym hasFlag PRIVATE ) buf.append(" | PRIVATE")
+ if (sym hasFlag STATIC ) buf.append(" | STATIC")
+ if (sym hasFlag SYNTHETIC ) buf.append(" | SYNTHETIC")
+ val attrs = ", attrs=" + (
+ if (!sym.attributes.isEmpty)
+ sym.attributes.map(annotationInfoToString).mkString("[", ",", "]")
+ else
+ tree.asInstanceOf[MemberDef].mods.annotations)
+ (if (buf.length() > 2) buf.substring(3)
+ else "0") + ", // flags=" + flagsToString(sym.flags) + attrs
+ }
+ def nodeinfo(tree: Tree) =
+ if (infolevel == InfoLevel.Quiet) ""
+ else {
+ val buf = new StringBuilder(" // sym=" + tree.symbol)
+ if (infolevel > InfoLevel.Quiet && tree.symbol != null)
+ buf.append(", sym.tpe=" + tree.symbol.tpe)
+ if (tree.hasSymbol)
+ if (tree.symbol.isPrimaryConstructor)
+ buf.append(", isPrimaryConstructor")
+ else if (tree.symbol.isConstructor)
+ buf.append(", isConstructor")
+ buf.append(", tpe=" + tree.tpe)
+ if (tree.tpe != null) {
+ val sym = tree.tpe.symbol
+ buf.append(", tpe.sym=" + sym)
+ if (sym != NoSymbol) {
+ buf.append(", tpe.sym.owner=" + sym.owner)
+ if ((infolevel > InfoLevel.Normal) &&
+ !(sym.owner eq definitions.ScalaPackageClass) &&
+ !sym.isModuleClass && !sym.isPackageClass &&
+ !sym.hasFlag(JAVA)) {
+ val members = for (m <- tree.tpe.decls.toList)
+ yield m.toString() + ": " + m.tpe + ", "
+ buf.append(", tpe.decls=" + members)
+ }
+ }
+ }
+ buf.toString
+ }
+ def nodeinfo2(tree: Tree) =
+ (if (comma) "," else "") + nodeinfo(tree)
+ tree match {
+ case AppliedTypeTree(tpt, args) =>
+ println("AppliedTypeTree(" + nodeinfo(tree))
+ traverse(tpt, level + 1, true)
+ if (args.isEmpty)
+ println(" List() // no argument")
+ else {
+ val n = args.length
+ println(" List( // " + n + " arguments(s)")
+ for (i <- 0 until n)
+ traverse(args(i), level + 2, i < n-1)
+ println(" )")
+ }
+ printcln(")")
+ case Apply(fun, args) =>
+ println("Apply(" + nodeinfo(tree))
+ traverse(fun, level + 1, true)
+ if (args.isEmpty)
+ println(" List() // no argument")
+ else {
+ val n = args.length
+ println(" List( // " + n + " argument(s)")
+ for (i <- 0 until n)
+ traverse(args(i), level + 2, i < n-1)
+ println(" )")
+ }
+ printcln(")")
+ case Block(stats, expr) =>
+ println("Block(")
+ if (stats.isEmpty)
+ println(" List() // no statement")
+ else {
+ val n = stats.length
+ println(" List( // " + n + " statement(s)")
+ for (i <- 0 until n)
+ traverse(stats(i), level + 2, i < n-1)
+ println(" )")
+ }
+ traverse(expr, level + 1, false)
+ printcln(")")
+ case ClassDef(mods, name, tparams, tpt, impl) =>
+ println("ClassDef(" + nodeinfo(tree))
+ println(" " + symflags(tree))
+ println(" \"" + name + "\",")
+ if (tparams.isEmpty)
+ println(" List(), // no type parameter")
+ else {
+ val n = tparams.length
+ println(" List( // " + n + " type parameter(s)")
+ for (i <- 0 until n)
+ traverse(tparams(i), level + 2, i < n-1)
+ println(" ),")
+ }
+ traverse(impl, level + 1, false)
+ printcln(")")
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ println("DefDef(" + nodeinfo(tree))
+ println(" " + symflags(tree))
+ println(" \"" + name + "\",")
+ if (tparams.isEmpty)
+ println(" List(), // no type parameter")
+ else {
+ val n = tparams.length
+ println(" List( // " + n + " type parameter(s)")
+ for (i <- 0 until n)
+ traverse(tparams(i), level + 2, i < n-1)
+ println(" ),")
+ }
+ traverse(rhs, level + 1, false)
+ printcln(")")
+ case EmptyTree =>
+ printcln("EmptyTree")
+ case Ident(name) =>
+ printcln("Ident(\"" + name + "\")" + nodeinfo2(tree))
+ case Literal(value) =>
+ printcln("Literal(" + value + ")")
+ case New(tpt) =>
+ println("New(" + nodeinfo(tree))
+ traverse(tpt, level + 1, false)
+ printcln(")")
+ case Select(qualifier, selector) =>
+ println("Select(" + nodeinfo(tree))
+ traverse(qualifier, level + 1, true)
+ printcln(" \"" + selector + "\")")
+ case Super(qual, mix) =>
+ printcln("Super(\"" + qual + "\", \"" + mix + "\")" + nodeinfo2(tree))
+ case Template(parents, body) =>
+ println("Template(,")
+ println(" " + parents.map(p => p.tpe.symbol) + ", // parents")
+ if (body.isEmpty)
+ println(" List() // no body")
+ else {
+ val n = body.length
+ println(" List( // body")
+ for (i <- 0 until n)
+ traverse(body(i), level + 2, i < n-1)
+ println(" )")
+ }
+ printcln(")")
+ case This(qual) =>
+ println("This(\"" + qual + "\")" + nodeinfo2(tree))
+ case TypeApply(fun, args) =>
+ println("TypeApply(" + nodeinfo(tree))
+ traverse(fun, level + 1, true)
+ if (args.isEmpty)
+ println(" List() // no argument")
+ else {
+ val n = args.length
+ println(" List(")
+ for (i <- 0 until n)
+ traverse(args(i), level + 1, i < n-1)
+ println(" )")
+ }
+ printcln(")")
+ case TypeTree() =>
+ printcln("TypeTree()" + nodeinfo2(tree))
+ case Typed(expr, tpt) =>
+ println("Typed(" + nodeinfo(tree))
+ traverse(expr, level + 1, true)
+ traverse(tpt, level + 1, false)
+ printcln(")")
+ case ValDef(mods, name, tpt, rhs) =>
+ println("ValDef(" + nodeinfo(tree))
+ println(" " + symflags(tree))
+ println(" \"" + name + "\",")
+ traverse(tpt, level + 1, true)
+ traverse(rhs, level + 1, false)
+ printcln(")")
+ case _ =>
+ printcln("***" + tree.getClass)
+ }
+ }
+ buf setLength 0
+ traverse(tree, 0, false)
+ buf.toString
+ }
+ }
+}