26
26
var infolevel = InfoLevel.Quiet
28
object nodeToString extends Function1[Tree, String] {
28
def nodeToString: Tree => String = nodeToRegularString
30
object nodeToRegularString extends DefaultPrintAST with (Tree => String) {
31
def apply(tree: Tree) = stringify(tree)
34
trait DefaultPrintAST extends PrintAST {
35
val printPos = settings.Xprintpos.value || settings.Yposdebug.value
37
def showNameAndPos(tree: NameTree) = showPosition(tree) + showName(tree.name)
38
def showDefTreeName(tree: DefTree) = showName(tree.name)
39
def showPosition(tree: Tree) = if (printPos) tree.pos.show else ""
40
def showFlags(tree: MemberDef) = flagsToString(tree.symbol.flags | tree.mods.flags)
41
def showLiteral(lit: Literal) = showPosition(lit) + lit.value.escapedStringValue
42
def showTypeTree(tt: TypeTree) = showPosition(tt) + "<tpt>" + emptyOrComment(showType(tt))
43
def showName(name: Name) = name match {
44
case nme.EMPTY | tpnme.EMPTY => "<empty>"
45
case name => "\"" + name + "\""
48
def showSymbol(tree: Tree): String = {
50
if (sym == null || sym == NoSymbol) ""
51
else sym.defString + sym.locationString
53
def showType(tree: Tree): String = {
55
if (tpe == null || tpe == NoType) ""
56
else "tree.tpe=" + tpe
59
def showAttributes(tree: Tree): String = {
60
if (infolevel == InfoLevel.Quiet) ""
62
try { List(showSymbol(tree), showType(tree)) filterNot (_ == "") mkString ", " trim }
63
catch { case ex: Throwable => "sym= <error> " + ex.getMessage }
29
69
private val buf = new StringBuilder
31
def apply(tree: Tree): String = {
32
def traverse(tree: Tree, level: Int, comma: Boolean) {
33
def println(s: String) {
34
for (i <- 0 until level) buf.append(" ")
38
def printcln(s: String) {
39
for (i <- 0 until level) buf.append(" ")
41
if (comma) buf.append(",")
44
def annotationInfoToString(annot: AnnotationInfo): String = {
45
val str = new StringBuilder
46
str.append(annot.atp.toString())
47
if (!annot.args.isEmpty)
48
str.append(annot.args.mkString("(", ",", ")"))
49
if (!annot.assocs.isEmpty)
50
for (((name, value), index) <- annot.assocs.zipWithIndex) {
53
str.append(name).append(" = ").append(value)
57
def symflags(tree: Tree): String = {
58
val buf = new StringBuffer
60
buf append flagsToString(sym.flags)
62
val annots = ", annots=" + (
63
if (!sym.annotations.isEmpty)
64
sym.annotations.map(annotationInfoToString).mkString("[", ",", "]")
66
tree.asInstanceOf[MemberDef].mods.annotations)
67
(if (buf.length() > 2) buf.substring(3)
68
else "0") + ", // flags=" + flagsToString(sym.flags) + annots
71
def nodeinfo(tree: Tree): String =
72
if (infolevel == InfoLevel.Quiet) ""
74
val buf = new StringBuilder(" // sym=" + tree.symbol)
76
if (tree.symbol.isPrimaryConstructor)
77
buf.append(", isPrimaryConstructor")
78
else if (tree.symbol.isConstructor)
79
buf.append(", isConstructor")
80
if (tree.symbol != NoSymbol)
81
buf.append(", sym.owner=" + tree.symbol.owner)
82
buf.append(", sym.tpe=" + tree.symbol.tpe)
84
buf.append(", tpe=" + tree.tpe)
85
if (tree.tpe != null) {
86
var sym = tree.tpe.termSymbol
87
if (sym == NoSymbol) sym = tree.tpe.typeSymbol
88
buf.append(", tpe.sym=" + sym)
89
if (sym != NoSymbol) {
90
buf.append(", tpe.sym.owner=" + sym.owner)
91
if ((infolevel > InfoLevel.Normal) &&
92
!(sym.owner eq definitions.ScalaPackageClass) &&
93
!sym.isModuleClass && !sym.isPackageClass &&
95
val members = for (m <- tree.tpe.decls.toList)
96
yield m.toString() + ": " + m.tpe + ", "
97
buf.append(", tpe.decls=" + members)
103
def nodeinfo2(tree: Tree): String =
104
(if (comma) "," else "") + nodeinfo(tree)
106
def applyCommon(name: String, tree: Tree, fun: Tree, args: List[Tree]) {
107
println(name + "(" + nodeinfo(tree))
108
traverse(fun, level + 1, true)
110
println(" Nil // no argument")
113
println(" List( // " + n + " arguments(s)")
115
traverse(args(i), level + 2, i < n-1)
122
case AppliedTypeTree(tpt, args) => applyCommon("AppliedTypeTree", tree, tpt, args)
123
case Apply(fun, args) => applyCommon("Apply", tree, fun, args)
124
case ApplyDynamic(fun, args) => applyCommon("ApplyDynamic", tree, fun, args)
126
case Block(stats, expr) =>
127
println("Block(" + nodeinfo(tree))
129
println(" List(), // no statement")
132
println(" List( // " + n + " statement(s)")
134
traverse(stats(i), level + 2, i < n-1)
137
traverse(expr, level + 1, false)
139
case ClassDef(mods, name, tparams, impl) =>
140
println("ClassDef(" + nodeinfo(tree))
141
println(" " + symflags(tree))
142
println(" \"" + name + "\",")
144
println(" List(), // no type parameter")
146
val n = tparams.length
147
println(" List( // " + n + " type parameter(s)")
149
traverse(tparams(i), level + 2, i < n-1)
152
traverse(impl, level + 1, false)
154
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
155
println("DefDef(" + nodeinfo(tree))
156
println(" " + symflags(tree))
157
println(" \"" + name + "\",")
159
println(" List(), // no type parameter")
161
val n = tparams.length
162
println(" List( // " + n + " type parameter(s)")
164
traverse(tparams(i), level + 2, i < n-1)
167
val n = vparamss.length
168
if (n == 1 && vparamss(0).isEmpty)
169
println(" List(List()), // no parameter")
172
for (i <- 0 until n) {
173
val m = vparamss(i).length
174
println(" List( // " + m + " parameter(s)")
176
traverse(vparamss(i)(j), level + 3, j < m-1)
181
println(" " + tpt + ",")
182
traverse(rhs, level + 1, false)
185
printcln("EmptyTree")
187
printcln("Ident(\"" + name + "\")" + nodeinfo2(tree))
188
case Literal(value) =>
189
printcln("Literal(" + value + ")")
191
println("New(" + nodeinfo(tree))
192
traverse(tpt, level + 1, false)
194
case Select(qualifier, selector) =>
195
println("Select(" + nodeinfo(tree))
196
traverse(qualifier, level + 1, true)
197
printcln(" \"" + selector + "\")")
198
case Super(qual, mix) =>
199
println("Super(\"" + mix + "\")" + nodeinfo(tree))
200
traverse(qual, level + 1, true)
201
case Template(parents, self, body) =>
202
println("Template(" + nodeinfo(tree))
203
println(" " + parents.map(p =>
204
if (p.tpe ne null) p.tpe.typeSymbol else "null-" + p
206
traverse(self, level + 1, true)
208
println(" List() // no body")
211
println(" List( // body")
213
traverse(body(i), level + 2, i < n-1)
218
println("This(\"" + qual + "\")" + nodeinfo2(tree))
219
case TypeApply(fun, args) =>
220
println("TypeApply(" + nodeinfo(tree))
221
traverse(fun, level + 1, true)
223
println(" List() // no argument")
228
traverse(args(i), level + 1, i < n-1)
233
printcln("TypeTree()" + nodeinfo2(tree))
234
case Typed(expr, tpt) =>
235
println("Typed(" + nodeinfo(tree))
236
traverse(expr, level + 1, true)
237
traverse(tpt, level + 1, false)
239
case ValDef(mods, name, tpt, rhs) =>
240
println("ValDef(" + nodeinfo(tree))
241
println(" " + symflags(tree))
242
println(" \"" + name + "\",")
243
traverse(tpt, level + 1, true)
244
traverse(rhs, level + 1, false)
246
case PackageDef(pid, stats) =>
247
println("PackageDef(")
248
traverse(pid, level + 1, false)
251
traverse(stat, level + 1, false)
256
if (p.productArity != 0) {
257
println(p.productPrefix+"(")
258
for (elem <- (0 until p.productArity) map p.productElement) {
259
def printElem(elem: Any, level: Int): Unit = elem match {
261
traverse(t, level, false)
264
for (x <- xs) printElem(x, level+1)
267
println(elem.toString)
269
printElem(elem, level+1)
272
} else printcln(p.productPrefix)
277
traverse(tree, 0, false)
72
def showName(name: Name): String
73
def showPosition(tree: Tree): String
74
def showNameAndPos(tree: NameTree): String
75
def showDefTreeName(defTree: DefTree): String
76
def showFlags(tree: MemberDef): String
77
def showLiteral(lit: Literal): String
78
def showTypeTree(tt: TypeTree): String
79
def showAttributes(tree: Tree): String // symbol and type
81
def showRefTreeName(tree: Tree): String = {
83
case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name)
84
case Select(qual, name) => showRefTreeName(qual) + "." + showName(name)
85
case id @ Ident(name) => showNameAndPos(id)
89
def showRefTree(tree: RefTree): String = {
90
def prefix0 = showRefTreeName(tree.qualifier)
91
def prefix = if (prefix0 == "") "" else (tree match {
92
case SelectFromTypeTree(_, _) => prefix0 + "#"
93
case Select(_, _) => prefix0 + "."
96
prefix + showNameAndPos(tree) + emptyOrComment(showAttributes(tree))
99
def emptyOrComment(s: String) = if (s == "") "" else " // " + s
101
def stringify(tree: Tree): String = {
103
if (settings.XshowtreesStringified.value) buf.append(tree.toString + EOL)
104
if (settings.XshowtreesCompact.value) {
105
buf.append(showRaw(tree, printIds = settings.uniqid.value, printTypes = settings.printtypes.value))
112
def traverseAny(x: Any) {
114
case t: Tree => traverse(t)
115
case xs: List[_] => printMultiline("List", "")(xs foreach traverseAny)
116
case _ => println("" + x)
119
def println(s: String) = printLine(s, "")
121
def printLine(value: String, comment: String) {
122
buf append " " * level
134
def annotationInfoToString(annot: AnnotationInfo): String = {
135
val str = new StringBuilder
136
str.append(annot.atp.toString())
137
if (!annot.args.isEmpty)
138
str.append(annot.args.mkString("(", ",", ")"))
139
if (!annot.assocs.isEmpty)
140
for (((name, value), index) <- annot.assocs.zipWithIndex) {
143
str.append(name).append(" = ").append(value)
147
def printModifiers(tree: MemberDef) {
148
// SI-5885: by default this won't print annotations of not yet initialized symbols
149
val annots0 = tree.symbol.annotations match {
150
case Nil => tree.mods.annotations
151
case xs => xs map annotationInfoToString
153
val annots = annots0 match {
155
case xs => " " + xs.mkString("@{ ", ", ", " }")
157
val flagString = showFlags(tree) match {
161
println(flagString + annots)
164
def applyCommon(tree: Tree, fun: Tree, args: List[Tree]) {
165
printMultiline(tree) {
167
traverseList("Nil", "argument")(args)
171
def treePrefix(tree: Tree) = showPosition(tree) + tree.productPrefix
172
def printMultiline(tree: Tree)(body: => Unit) {
173
printMultiline(treePrefix(tree), showAttributes(tree))(body)
175
def printMultiline(prefix: String, comment: String)(body: => Unit) {
176
printLine(prefix + "(", comment)
181
@inline private def indent[T](body: => T): T = {
187
def traverseList(ifEmpty: String, what: String)(trees: List[Tree]) {
190
else if (trees.tail.isEmpty)
193
printLine("", trees.length + " " + what + "s")
194
trees foreach traverse
198
def printSingle(tree: Tree, name: Name) {
199
println(treePrefix(tree) + "(" + showName(name) + ")" + showAttributes(tree))
202
def traverse(tree: Tree) {
206
case AppliedTypeTree(tpt, args) => applyCommon(tree, tpt, args)
207
case ApplyDynamic(fun, args) => applyCommon(tree, fun, args)
208
case Apply(fun, args) => applyCommon(tree, fun, args)
210
case Throw(Ident(name)) =>
211
printSingle(tree, name)
213
case b @ Bind(name, body) =>
214
printMultiline(tree) {
215
println(showDefTreeName(b))
219
case ld @ LabelDef(name, params, rhs) =>
220
printMultiline(tree) {
222
traverseList("()", "params")(params)
226
case Function(vparams, body) =>
227
printMultiline(tree) {
228
traverseList("()", "parameter")(vparams)
231
case Try(block, catches, finalizer) =>
232
printMultiline(tree) {
234
traverseList("{}", "case")(catches)
235
if (finalizer ne EmptyTree)
239
case Match(selector, cases) =>
240
printMultiline(tree) {
242
traverseList("", "case")(cases)
244
case CaseDef(pat, guard, body) =>
245
printMultiline(tree) {
247
if (guard ne EmptyTree)
251
case Block(stats, expr) =>
252
printMultiline(tree) {
253
traverseList("{}", "statement")(stats)
256
case cd @ ClassDef(mods, name, tparams, impl) =>
257
printMultiline(tree) {
259
println(showDefTreeName(cd))
260
traverseList("[]", "type parameter")(tparams)
263
case md @ ModuleDef(mods, name, impl) =>
264
printMultiline(tree) {
266
println(showDefTreeName(md))
269
case dd @ DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
270
printMultiline(tree) {
272
println(showDefTreeName(dd))
273
traverseList("[]", "type parameter")(tparams)
275
case Nil => println("Nil")
276
case Nil :: Nil => println("List(Nil)")
278
printLine("", "1 parameter list")
281
printLine("", pss.length + " parameter lists")
282
pss foreach (ps => traverseList("()", "parameter")(ps))
288
println(showName(nme.EMPTY))
289
case lit @ Literal(value) =>
290
println(showLiteral(lit))
292
printMultiline(tree)(traverse(tpt))
293
case Super(This(qual), mix) =>
294
println("Super(This(" + showName(qual) + "), " + showName(mix) + ")")
295
case Super(qual, mix) =>
296
printMultiline(tree) {
300
case Template(parents, self, body) =>
301
printMultiline(tree) {
302
val ps0 = parents map { p =>
303
if (p.tpe eq null) p match {
304
case x: RefTree => showRefTree(x)
305
case x => showPosition(x) + x
307
else showName(newTypeName(p.tpe.typeSymbol.fullName))
309
printLine(ps0 mkString ", ", "parents")
311
traverseList("{}", "statement")(body)
314
printSingle(tree, qual)
315
case TypeApply(fun, args) =>
316
printMultiline(tree) {
318
traverseList("[]", "type argument")(args)
320
case tt @ TypeTree() =>
321
println(showTypeTree(tt))
323
case Typed(expr, tpt) =>
324
printMultiline(tree) {
328
case vd @ ValDef(mods, name, tpt, rhs) =>
329
printMultiline(tree) {
331
println(showDefTreeName(vd))
335
case td @ TypeDef(mods, name, tparams, rhs) =>
336
printMultiline(tree) {
338
println(showDefTreeName(td))
339
traverseList("[]", "type parameter")(tparams)
343
case PackageDef(pid, stats) =>
344
printMultiline("PackageDef", "")(pid :: stats foreach traverse)
348
case t: RefTree => println(showRefTree(t))
349
case t if t.productArity == 0 => println(treePrefix(t))
350
case t => printMultiline(tree)(tree.productIterator foreach traverseAny)
282
356
def printUnit(unit: CompilationUnit) {