summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-11-19 18:41:06 +0000
committerMartin Odersky <odersky@gmail.com>2011-11-19 18:41:06 +0000
commit943d2cfb07cb978e096eead09dc24581a0974333 (patch)
tree91e529784cc81733a07e1dcad01024975aa9cec2
parent6d5a16b3821375386b09bfd944be8ec93bd7e82c (diff)
downloadscala-943d2cfb07cb978e096eead09dc24581a0974333.tar.gz
scala-943d2cfb07cb978e096eead09dc24581a0974333.tar.bz2
scala-943d2cfb07cb978e096eead09dc24581a0974333.zip
Partial cleanup and generalization of tree prin...
Partial cleanup and generalization of tree printing. You can now print a tree in direct case class form with `showRaw(tree)`. Should make NodePrinters redundant.
-rw-r--r--src/compiler/scala/reflect/internal/TreePrinters.scala141
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala9
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala120
-rwxr-xr-xsrc/library/scala/reflect/api/Symbols.scala3
-rw-r--r--src/library/scala/reflect/api/TreePrinters.scala59
-rw-r--r--src/library/scala/reflect/api/Trees.scala4
-rwxr-xr-xsrc/library/scala/reflect/api/Universe.scala1
8 files changed, 179 insertions, 160 deletions
diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala
index e5b9fafa00..c86cd9b29c 100644
--- a/src/compiler/scala/reflect/internal/TreePrinters.scala
+++ b/src/compiler/scala/reflect/internal/TreePrinters.scala
@@ -9,7 +9,7 @@ package internal
import java.io.{ OutputStream, PrintWriter, StringWriter, Writer }
import Flags._
-trait TreePrinters { self: SymbolTable =>
+trait TreePrinters extends api.TreePrinters { self: SymbolTable =>
//nsc import treeInfo.{ IsTrue, IsFalse }
@@ -33,17 +33,18 @@ trait TreePrinters { self: SymbolTable =>
case _ => t.toString
}
- class TreePrinter(out: PrintWriter) {
+ class TreePrinter(out: PrintWriter) extends super.TreePrinter {
protected var indentMargin = 0
protected val indentStep = 2
protected var indentString = " " // 40
- def flush() = out.flush()
+ typesPrinted = settings.printtypes.value
+ uniqueIds = settings.uniqid.value
+ protected def doPrintPositions = settings.Xprintpos.value
def indent() = indentMargin += indentStep
def undent() = indentMargin -= indentStep
- protected def doPrintPositions = settings.Xprintpos.value
def printPosition(tree: Tree) = if (doPrintPositions) print(showPos(tree.pos))
def println() {
@@ -64,11 +65,11 @@ trait TreePrinters { self: SymbolTable =>
def printColumn(ts: List[Tree], start: String, sep: String, end: String) {
print(start); indent; println()
- printSeq(ts){print}{print(sep); println()}; undent; println(); print(end)
+ printSeq(ts){print(_)}{print(sep); println()}; undent; println(); print(end)
}
def printRow(ts: List[Tree], start: String, sep: String, end: String) {
- print(start); printSeq(ts){print}{print(sep)}; print(end)
+ print(start); printSeq(ts){print(_)}{print(sep)}; print(end)
}
def printRow(ts: List[Tree], sep: String) { printRow(ts, "", sep, "") }
@@ -120,7 +121,8 @@ trait TreePrinters { self: SymbolTable =>
private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = {
def nameFn(sym: Symbol) = {
val prefix = if (sym.isMixinConstructor) "/*%s*/".format(quotedName(sym.owner.name, decoded)) else ""
- prefix + tree.symbol.nameString
+ val suffix = if (uniqueIds) "#"+sym.id else ""
+ prefix + tree.symbol.decodedName + suffix
}
symFn(tree, nameFn, quotedName(name, decoded))
}
@@ -129,7 +131,7 @@ trait TreePrinters { self: SymbolTable =>
def symName(tree: Tree, name: Name) = symNameInternal(tree, name, false)
def printOpt(prefix: String, tree: Tree) {
- if (!tree.isEmpty) { print(prefix); print(tree) }
+ if (!tree.isEmpty) { print(prefix, tree) }
}
def printModifiers(tree: Tree, mods: Modifiers): Unit = printFlags(
@@ -154,13 +156,10 @@ trait TreePrinters { self: SymbolTable =>
annots foreach (annot => print("@"+annot+" "))
}
- def print(str: String) { out.print(str) }
- def print(name: Name) { print(quotedName(name)) }
-
private var currentOwner: Symbol = NoSymbol
private var selectorType: Type = NoType
- def printRaw(tree: Tree) {
+ def printTree(tree: Tree) {
tree match {
case EmptyTree =>
print("<empty>")
@@ -173,29 +172,26 @@ trait TreePrinters { self: SymbolTable =>
else if (ifSym(tree, _.isModuleClass)) "object"
else "class"
- print(word + " " + symName(tree, name))
+ print(word, " ", symName(tree, name))
printTypeParams(tparams)
- print(if (mods.isDeferred) " <: " else " extends "); print(impl)
+ print(if (mods.isDeferred) " <: " else " extends ", impl)
case PackageDef(packaged, stats) =>
printAnnotations(tree)
- print("package "); print(packaged); printColumn(stats, " {", ";", "}")
+ print("package ", packaged); printColumn(stats, " {", ";", "}")
case ModuleDef(mods, name, impl) =>
printAnnotations(tree)
- printModifiers(tree, mods); print("object " + symName(tree, name))
- print(" extends "); print(impl)
+ printModifiers(tree, mods);
+ print("object " + symName(tree, name), " extends ", impl)
case ValDef(mods, name, tp, rhs) =>
printAnnotations(tree)
printModifiers(tree, mods)
- print(if (mods.isMutable) "var " else "val ")
- print(symName(tree, name))
+ print(if (mods.isMutable) "var " else "val ", symName(tree, name))
printOpt(": ", tp)
- if (!mods.isDeferred) {
- print(" = ")
- if (rhs.isEmpty) print("_") else print(rhs)
- }
+ if (!mods.isDeferred)
+ print(" = ", if (rhs.isEmpty) "_" else rhs)
case DefDef(mods, name, tparams, vparamss, tp, rhs) =>
printAnnotations(tree)
@@ -225,16 +221,12 @@ trait TreePrinters { self: SymbolTable =>
if (isNotRemap(s)) from
else from + "=>" + quotedName(s.rename)
}
- print("import "); print(backquotedPath(expr))
- print(".")
+ print("import ", backquotedPath(expr), ".")
selectors match {
case List(s) =>
// If there is just one selector and it is not remapping a name, no braces are needed
- if (isNotRemap(s)) {
- print(selectorToString(s))
- } else {
- print("{"); print(selectorToString(s)); print("}")
- }
+ if (isNotRemap(s)) print(selectorToString(s))
+ else print("{", selectorToString(s), "}")
// If there is more than one selector braces are always needed
case many =>
print(many.map(selectorToString).mkString("{", ", ", "}"))
@@ -246,9 +238,9 @@ trait TreePrinters { self: SymbolTable =>
printRow(parents, " with ")
if (!body.isEmpty) {
if (self.name != nme.WILDCARD) {
- print(" { "); print(self.name); printOpt(": ", self.tpt); print(" => ")
+ print(" { ", self.name); printOpt(": ", self.tpt); print(" => ")
} else if (!self.tpt.isEmpty) {
- print(" { _ : "); print(self.tpt); print(" => ")
+ print(" { _ : ", self.tpt, " => ")
} else {
print(" {")
}
@@ -276,39 +268,39 @@ trait TreePrinters { self: SymbolTable =>
patConstr(pat).tpe.finalResultType, selectorType, currentOwner))
print("???")
print(pat); printOpt(" if ", guard)
- print(" => "); print(body)
+ print(" => ", body)
case Alternative(trees) =>
printRow(trees, "(", "| ", ")")
case Star(elem) =>
- print("("); print(elem); print(")*")
+ print("(", elem, ")*")
case Bind(name, t) =>
- print("("); print(symName(tree, name)); print(" @ "); print(t); print(")")
+ print("(", symName(tree, name), " @ ", t, ")")
case UnApply(fun, args) =>
- print(fun); print(" <unapply> "); printRow(args, "(", ", ", ")")
+ print(fun, " <unapply> "); printRow(args, "(", ", ", ")")
case ArrayValue(elemtpt, trees) =>
- print("Array["); print(elemtpt); printRow(trees, "]{", ", ", "}")
+ print("Array[", elemtpt); printRow(trees, "]{", ", ", "}")
case Function(vparams, body) =>
- print("("); printValueParams(vparams); print(" => "); print(body); print(")")
- if (settings.uniqid.value && tree.symbol != null) print("#"+tree.symbol.id)
+ print("("); printValueParams(vparams); print(" => ", body, ")")
+ if (uniqueIds && tree.symbol != null) print("#"+tree.symbol.id)
case Assign(lhs, rhs) =>
- print(lhs); print(" = "); print(rhs)
+ print(lhs, " = ", rhs)
case If(cond, thenp, elsep) =>
- print("if ("); print(cond); print(")"); indent; println()
+ print("if (", cond, ")"); indent; println()
print(thenp); undent
if (!elsep.isEmpty) {
println(); print("else"); indent; println(); print(elsep); undent
}
case Return(expr) =>
- print("return "); print(expr)
+ print("return ", expr)
case Try(block, catches, finalizer) =>
print("try "); printBlock(block)
@@ -316,13 +308,13 @@ trait TreePrinters { self: SymbolTable =>
printOpt(" finally ", finalizer)
case Throw(expr) =>
- print("throw "); print(expr)
+ print("throw ", expr)
case New(tpe) =>
- print("new "); print(tpe)
+ print("new ", tpe)
case Typed(expr, tp) =>
- print("("); print(expr); print(": "); print(tp); print(")")
+ print("(", expr, ": ", tp, ")")
case TypeApply(fun, targs) =>
print(fun); printRow(targs, "[", ", ", "]")
@@ -331,7 +323,7 @@ trait TreePrinters { self: SymbolTable =>
print(fun); printRow(vargs, "(", ", ", ")")
case ApplyDynamic(qual, vargs) =>
- print("<apply-dynamic>("); print(qual); print("#"); print(tree.symbol.nameString)
+ print("<apply-dynamic>(", qual, "#", tree.symbol.nameString)
printRow(vargs, ", (", ", ", "))")
case Super(This(qual), mix) =>
@@ -341,8 +333,7 @@ trait TreePrinters { self: SymbolTable =>
print("[" + mix + "]")
case Super(qual, mix) =>
- print(qual)
- print(".super")
+ print(qual, ".super")
if (!mix.isEmpty)
print("[" + mix + "]")
@@ -354,7 +345,7 @@ trait TreePrinters { self: SymbolTable =>
print(qual)
case Select(qualifier, name) =>
- print(backquotedPath(qualifier)); print("."); print(symName(tree, name))
+ print(backquotedPath(qualifier), ".", symName(tree, name))
case Ident(name) =>
print(symName(tree, name))
@@ -363,29 +354,29 @@ trait TreePrinters { self: SymbolTable =>
print(x.escapedStringValue)
case tt: TypeTree =>
- if ((tree.tpe eq null) || (settings.Xprintpos.value && tt.original != null)) {
- if (tt.original != null) { print("<type: "); print(tt.original); print(">") }
+ if ((tree.tpe eq null) || (doPrintPositions && tt.original != null)) {
+ if (tt.original != null) print("<type: ", tt.original, ">")
else print("<type ?>")
} else if ((tree.tpe.typeSymbol ne null) && tree.tpe.typeSymbol.isAnonymousClass) {
- print(tree.tpe.typeSymbol.toString())
+ print(tree.tpe.typeSymbol.toString)
} else {
- print(tree.tpe.toString())
+ print(tree.tpe.toString)
}
case Annotated(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), tree) =>
def printAnnot() {
- print("@"); print(tpt)
+ print("@", tpt)
if (!args.isEmpty)
printRow(args, "(", ",", ")")
}
- if (tree.isType) { print(tree); print(" "); printAnnot() }
- else { print(tree); print(": "); printAnnot() }
+ print(tree, if (tree.isType) " " else ": ")
+ printAnnot()
case SingletonTypeTree(ref) =>
- print(ref); print(".type")
+ print(ref, ".type")
case SelectFromTypeTree(qualifier, selector) =>
- print(qualifier); print("#"); print(symName(tree, selector))
+ print(qualifier, "#", symName(tree, selector))
case CompoundTypeTree(templ) =>
print(templ)
@@ -408,34 +399,26 @@ trait TreePrinters { self: SymbolTable =>
case tree =>
- xprintRaw(this, tree)
+ xprintTree(this, tree)
}
- if (settings.printtypes.value && tree.isTerm && !tree.isEmpty) {
- print("{"); print(if (tree.tpe eq null) "<null>" else tree.tpe.toString()); print("}")
+ if (typesPrinted && tree.isTerm && !tree.isEmpty) {
+ print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
}
}
- def print(tree: Tree) {
- printPosition(tree)
- printRaw(
- //nsc if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) {
- //nsc tree match {
- //nsc case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body))
- //nsc if (tree.symbol.thisSym != tree.symbol) =>
- //nsc ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body))
- //nsc case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl)
- //nsc case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl)
- //nsc case ValDef(_, _, _, rhs) => ValDef(tree.symbol, rhs)
- //nsc case DefDef(_, _, _, vparamss, _, rhs) => DefDef(tree.symbol, vparamss, rhs)
- //nsc case TypeDef(_, _, _, rhs) => TypeDef(tree.symbol, rhs)
- //nsc case _ => tree
- //nsc }
- //nsc } else
- tree)
+ def print(args: Any*): Unit = args foreach {
+ case tree: Tree =>
+ printPosition(tree)
+ printTree(tree)
+ case name: Name =>
+ print(quotedName(name))
+ case arg =>
+ out.print(arg.toString)
}
}
- def xprintRaw(treePrinter: TreePrinter, tree: Tree) =
+ /** Hook for extensions */
+ def xprintTree(treePrinter: TreePrinter, tree: Tree) =
treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")"))
def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index ff1b759290..9a9b34a391 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -6,7 +6,6 @@
package scala.reflect
package internal
-import java.io.{ PrintWriter, StringWriter }
import Flags._
import api.Modifier
@@ -97,14 +96,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
// --- extension methods --------------------------------------------------------
- override def show(tree: Tree): String = {
- val buffer = new StringWriter()
- val printer = newTreePrinter(new PrintWriter(buffer))
- printer.print(tree)
- printer.flush()
- buffer.toString
- }
-
implicit def treeOps(tree: Tree): TreeOps = new TreeOps(tree)
class TreeOps(tree: Tree) {
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index fcbcb94e94..947a31cd7a 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1290,7 +1290,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
def printAllUnits() {
print("[[syntax trees at end of " + phase + "]]")
- atPhase(phase.next) { currentRun.units foreach treePrinter.print }
+ atPhase(phase.next) { currentRun.units foreach (treePrinter.print(_)) }
}
private def findMemberFromRoot(fullName: Name): Symbol = {
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 34f8cdc626..5c3071739c 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -16,56 +16,52 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
class TreePrinter(out: PrintWriter) extends super.TreePrinter(out) {
- override def print(tree: Tree) {
- printPosition(tree)
- printRaw(
- if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) {
- tree match {
- case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body))
- if (tree.symbol.thisSym != tree.symbol) =>
- ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body))
- case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl)
- case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl)
- case ValDef(_, _, _, rhs) => ValDef(tree.symbol, rhs)
- case DefDef(_, _, _, vparamss, _, rhs) => DefDef(tree.symbol, vparamss, rhs)
- case TypeDef(_, _, _, rhs) => TypeDef(tree.symbol, rhs)
- case _ => tree
- }
- } else tree)
- }
-
- def print(unit: CompilationUnit) {
- print("// Scala source: " + unit.source + "\n")
- if (unit.body == null) print("<null>")
- else { print(unit.body); println() }
-
- println()
- flush()
+ override def print(args: Any*): Unit = args foreach {
+ case tree: Tree =>
+ printPosition(tree)
+ printTree(
+ if (tree.isDef && tree.symbol != NoSymbol && tree.symbol.isInitialized) {
+ tree match {
+ case ClassDef(_, _, _, impl @ Template(ps, emptyValDef, body))
+ if (tree.symbol.thisSym != tree.symbol) =>
+ ClassDef(tree.symbol, Template(ps, ValDef(tree.symbol.thisSym), body))
+ case ClassDef(_, _, _, impl) => ClassDef(tree.symbol, impl)
+ case ModuleDef(_, _, impl) => ModuleDef(tree.symbol, impl)
+ case ValDef(_, _, _, rhs) => ValDef(tree.symbol, rhs)
+ case DefDef(_, _, _, vparamss, _, rhs) => DefDef(tree.symbol, vparamss, rhs)
+ case TypeDef(_, _, _, rhs) => TypeDef(tree.symbol, rhs)
+ case _ => tree
+ }
+ } else tree)
+ case unit: CompilationUnit =>
+ print("// Scala source: " + unit.source + "\n")
+ if (unit.body == null) print("<null>")
+ else { print(unit.body); println() }
+ println()
+ out.flush()
+ case arg =>
+ super.print(arg)
}
}
// overflow cases missing from TreePrinter in reflect.api
- override def xprintRaw(treePrinter: super.TreePrinter, tree: Tree) = tree match {
+ override def xprintTree(treePrinter: super.TreePrinter, tree: Tree) = tree match {
case DocDef(comment, definition) =>
treePrinter.print(comment.raw)
treePrinter.println()
treePrinter.print(definition)
case AssignOrNamedArg(lhs, rhs) =>
- treePrinter.print(lhs)
- treePrinter.print(" = ")
- treePrinter.print(rhs)
+ treePrinter.print(lhs, " = ", rhs)
case TypeTreeWithDeferredRefCheck() =>
treePrinter.print("<tree with deferred refcheck>")
case SelectFromArray(qualifier, name, _) =>
- treePrinter.print(qualifier)
- treePrinter.print(".<arr>")
- treePrinter.print(treePrinter.symName(tree, name))
+ treePrinter.print(qualifier, ".<arr>", treePrinter.symName(tree, name))
case _ =>
- super.xprintRaw(treePrinter, tree)
+ super.xprintTree(treePrinter, tree)
}
/** A tree printer which is stingier about vertical whitespace and unnecessary
@@ -74,7 +70,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
class CompactTreePrinter(out: PrintWriter) extends TreePrinter(out) {
override def printRow(ts: List[Tree], start: String, sep: String, end: String) {
print(start)
- printSeq(ts)(print)(print(sep))
+ printSeq(ts)(print(_))(print(sep))
print(end)
}
@@ -94,21 +90,21 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
def maybenot(tvalue: Boolean) = if (tvalue) "" else "!"
print("%s(" format maybenot(t1._2))
- printRaw(t1._1)
+ printTree(t1._1)
print(") %s %s(".format(op, maybenot(t2._2)))
- printRaw(t2._1)
+ printTree(t2._1)
print(")")
}
- override def printRaw(tree: Tree): Unit = {
+ override def printTree(tree: Tree): Unit = {
// routing supercalls through this for debugging ease
- def s() = super.printRaw(tree)
+ def s() = super.printTree(tree)
tree match {
// labels used for jumps - does not map to valid scala code
case LabelDef(name, params, rhs) =>
print("labeldef %s(%s) = ".format(name, params mkString ","))
- printRaw(rhs)
+ printTree(rhs)
case Ident(name) =>
print(decodedSymName(tree, name))
@@ -121,37 +117,37 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
printLogicalAnd(target -> true, arg -> true)
else (target, arg) match {
case (_: Ident, _: Literal | _: Ident) =>
- printRaw(target)
+ printTree(target)
print(" ")
- printRaw(Ident(method))
+ printTree(Ident(method))
print(" ")
- printRaw(arg)
+ printTree(arg)
case _ => s()
}
// target.unary_! ==> !target
case Select(qualifier, name) if (name.decode startsWith "unary_") =>
print(name.decode drop 6)
- printRaw(qualifier)
+ printTree(qualifier)
case Select(qualifier, name) =>
- printRaw(qualifier)
+ printTree(qualifier)
print(".")
print(quotedName(name, true))
// target.toString() ==> target.toString
- case Apply(fn, Nil) => printRaw(fn)
+ case Apply(fn, Nil) => printTree(fn)
// if a Block only continues one actual statement, just print it.
case Block(stats, expr) =>
allStatements(tree) match {
- case List(x) => printRaw(x)
+ case List(x) => printTree(x)
case xs => s()
}
// We get a lot of this stuff
- case If( IsTrue(), x, _) => printRaw(x)
- case If(IsFalse(), _, x) => printRaw(x)
+ case If( IsTrue(), x, _) => printTree(x)
+ case If(IsFalse(), _, x) => printTree(x)
case If(cond, IsTrue(), elsep) => printLogicalOr(cond -> true, elsep -> true)
case If(cond, IsFalse(), elsep) => printLogicalAnd(cond -> false, elsep -> true)
@@ -161,7 +157,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
// If thenp or elsep has only one statement, it doesn't need more than one line.
case If(cond, thenp, elsep) =>
def ifIndented(x: Tree) = {
- indent ; println() ; printRaw(x) ; undent
+ indent ; println() ; printTree(x) ; undent
}
val List(thenStmts, elseStmts) = List(thenp, elsep) map allStatements
@@ -169,16 +165,16 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
thenStmts match {
case List(x: If) => ifIndented(x)
- case List(x) => printRaw(x)
- case _ => printRaw(thenp)
+ case List(x) => printTree(x)
+ case _ => printTree(thenp)
}
if (elseStmts.nonEmpty) {
print(" else")
indent ; println()
elseStmts match {
- case List(x) => printRaw(x)
- case _ => printRaw(elsep)
+ case List(x) => printTree(x)
+ case _ => printTree(elsep)
}
undent ; println()
}
@@ -192,10 +188,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
* the natural course of events.
*/
class SafeTreePrinter(out: PrintWriter) extends TreePrinter(out) {
- override def print(tree: Tree) {
- printPosition(tree)
- printRaw(tree)
- }
+
private def default(t: Tree) = t.getClass.getName.reverse.takeWhile(_ != '.').reverse
private def params(trees: List[Tree]): String = trees map safe mkString ", "
@@ -209,7 +202,7 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
case _ => "(?: %s)".format(default(tree))
}
- override def printRaw(tree: Tree) { print(safe(tree)) }
+ override def printTree(tree: Tree) { print(safe(tree)) }
}
class TreeMatchTemplate {
@@ -286,15 +279,8 @@ trait TreePrinters extends reflect.internal.TreePrinters { this: Global =>
}
}
- private def asStringInternal(t: Tree, f: PrintWriter => TreePrinter): String = {
- val buffer = new StringWriter()
- val printer = f(new PrintWriter(buffer))
- printer.print(t)
- printer.flush()
- buffer.toString
- }
- def asString(t: Tree): String = asStringInternal(t, newStandardTreePrinter)
- def asCompactString(t: Tree): String = asStringInternal(t, newCompactTreePrinter)
+ def asString(t: Tree): String = show(t, newStandardTreePrinter)
+ def asCompactString(t: Tree): String = show(t, newCompactTreePrinter)
def newStandardTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newStandardTreePrinter(stream: OutputStream): TreePrinter = newStandardTreePrinter(new PrintWriter(stream))
diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala
index 3c4408aacd..31bcdebe7e 100755
--- a/src/library/scala/reflect/api/Symbols.scala
+++ b/src/library/scala/reflect/api/Symbols.scala
@@ -36,6 +36,9 @@ trait Symbols { self: Universe =>
*/
def fullName: String
+ /** An id number which is unique for all symbols in this universe */
+ def id: Int
+
/**
* Set when symbol has a modifier of the form private[X], NoSymbol otherwise.
*
diff --git a/src/library/scala/reflect/api/TreePrinters.scala b/src/library/scala/reflect/api/TreePrinters.scala
new file mode 100644
index 0000000000..15fba0e418
--- /dev/null
+++ b/src/library/scala/reflect/api/TreePrinters.scala
@@ -0,0 +1,59 @@
+package scala.reflect
+package api
+
+import java.io.{ PrintWriter, StringWriter }
+
+trait TreePrinters { self: Universe =>
+
+ trait TreePrinter {
+ def print(args: Any*)
+ protected var typesPrinted = false
+ protected var uniqueIds = false
+ def withTypesPrinted: this.type = { typesPrinted = true; this }
+ def withUniqueIds: this.type = { uniqueIds = true; this }
+ }
+
+ def show(tree: Tree, mkPrinter: PrintWriter => TreePrinter = newTreePrinter): String = {
+ val buffer = new StringWriter()
+ val writer = new PrintWriter(buffer)
+ val printer = mkPrinter(writer)
+ printer.print(tree)
+ writer.flush()
+ buffer.toString
+ }
+
+ def showRaw(tree: Tree): String = show(tree, new RawTreePrinter(_))
+
+ /** Hook to define what `show(tree)` means.
+ */
+ def newTreePrinter(out: PrintWriter): TreePrinter
+
+ class RawTreePrinter(out: PrintWriter) extends TreePrinter {
+ def print(args: Any*): Unit = args foreach {
+ case EmptyTree =>
+ print("EmptyTree")
+ case tree @ TypeTree() =>
+ print("TypeTree()")
+ if (tree.tpe != null)
+ print(".setType(", tree.tpe, ")")
+ else if (tree.original != null)
+ print(".setOriginal(", tree.original, ")")
+ case tree: Tree =>
+ print(tree.productPrefix+"(")
+ val it = tree.productIterator
+ while (it.hasNext) {
+ it.next() match {
+ case name: Name if uniqueIds && tree.hasSymbol && tree.symbol != NoSymbol =>
+ print(tree.symbol.name, "#", tree.symbol.id)
+ case arg =>
+ print(arg)
+ }
+ print(if (it.hasNext) ", " else ")")
+ }
+ if (typesPrinted)
+ print(".setType(", tree.tpe, ")")
+ case arg =>
+ out.print(arg)
+ }
+ }
+}
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 64793fb303..478c47a210 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -16,10 +16,6 @@ trait Trees /*extends reflect.generic.Trees*/ { self: Universe =>
type Modifiers <: AbsModifiers
- /** Hook to define what toString means on a tree
- */
- def show(tree: Tree): String
-
abstract class AbsModifiers {
def hasModifier(mod: Modifier.Value): Boolean
def allModifiers: Set[Modifier.Value]
diff --git a/src/library/scala/reflect/api/Universe.scala b/src/library/scala/reflect/api/Universe.scala
index ad145b12ac..03acbdda2c 100755
--- a/src/library/scala/reflect/api/Universe.scala
+++ b/src/library/scala/reflect/api/Universe.scala
@@ -8,6 +8,7 @@ abstract class Universe extends Symbols
with Names
with Trees
with Positions
+ with TreePrinters
with AnnotationInfos
with StandardDefinitions {
type Position