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:
parent
a766be553b
commit
7bf75564fc
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ abstract class Universe extends Symbols
|
|||
with Names
|
||||
with Trees
|
||||
with Positions
|
||||
with TreePrinters
|
||||
with AnnotationInfos
|
||||
with StandardDefinitions {
|
||||
type Position
|
||||
|
|
|
|||
Loading…
Reference in New Issue