You could take a look at the scaladoc (http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html#trees) or at the slides (http://scalamacros.org/talks/2012-04-28-MetaprogrammingInScala210.pdf, the "Learn to learn" part).
Here's what I usually do. I wrote a simple script called parse
, which takes Scala code as an argument and then compiles it with -Xprint:parser -Ystop-after:parser -Yshow-trees-stringified -Yshow-trees-compact
(parse
uses another helper script: adhoc-scalac
. click here to see its sources as well).
The advantage this approach has over showRaw
is that it doesn't require the code to typecheck. You could write a small snippet of code, which refers to non-existent variables or classes, and it still will successfully run and show you the AST. Here's an example of output:
09:26 ~$ parse 'class C { def x = 2 }'
[[syntax trees at end of parser]]// Scala source: tmp36sVGp
package <empty> {
class C extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
def x = 2
}
}
PackageDef(Ident(TermName("<empty>")), List(ClassDef(Modifiers(), TypeName("C"), List(), Template(List(Select(Ident(scala), TypeName("AnyRef"))), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))), DefDef(Modifiers(), TermName("x"), List(), List(), TypeTree(), Literal(Constant(2))))))))
There's also a script called typecheck
, which does the same, but stops after typer
. That's sometimes useful to understand how exactly the typechecker transforms the parser trees. However, both toolboxes and macros work with parser trees, so I use typecheck
for tree construction purposes very rarely.