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.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@26035 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
odersky 2011-11-19 18:41:06 +00:00
parent a766be553b
commit 7bf75564fc
8 changed files with 183 additions and 164 deletions

View File

@ -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, "") }
@ -116,11 +117,12 @@ trait TreePrinters { self: SymbolTable =>
case sym => f(sym)
}
private def ifSym(tree: Tree, p: Symbol => Boolean) = symFn(tree, p, false)
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)

View File

@ -6,7 +6,6 @@
package scala.reflect
package internal
import java.io.{ PrintWriter, StringWriter }
import Flags._
import api.Modifier
@ -96,15 +95,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
lazy val NoMods = Modifiers(0)
// --- 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) {

View File

@ -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 = {

View File

@ -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))

View File

@ -35,6 +35,9 @@ trait Symbols { self: Universe =>
* are separated by periods.
*/
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.

View File

@ -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)
}
}
}

View File

@ -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]

View File

@ -8,6 +8,7 @@ abstract class Universe extends Symbols
with Names
with Trees
with Positions
with TreePrinters
with AnnotationInfos
with StandardDefinitions {
type Position