たまに使いたくなった時には忘れていて、しかもなんか調べにくいのでオプションをメモっておくことに。
Scalaでは、scala/scalacコマンドなどでのASTを-Xprintオプションで出力させることができるのですが、出力させるフェーズを指定する必要があります。
それを確認するのが、「-Xshow-phases」。
$ scalac -Xshow-phases phase name id description ---------- -- ----------- parser 1 parse source into ASTs, perform simple desugaring namer 2 resolve names, attach symbols to named trees packageobjects 3 load package objects typer 4 the meat and potatoes: type the trees patmat 5 translate match expressions superaccessors 6 add super accessors in traits and nested classes extmethods 7 add extension methods for inline classes pickler 8 serialize symbol tables refchecks 9 reference/override checking, translate nested objects selectiveanf 10 selectivecps 11 uncurry 12 uncurry, translate function values to anonymous classes tailcalls 13 replace tail calls by jumps specialize 14 @specialized-driven class and method specialization explicitouter 15 this refs to outer pointers, translate patterns erasure 16 erase types, add interfaces for traits posterasure 17 clean up erased inline classes lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs lambdalift 19 move nested functions to top level constructors 20 move field definitions into constructors flatten 21 eliminate inner classes mixin 22 mixin composition cleanup 23 platform-specific cleanups, generate reflective calls icode 24 generate portable intermediate code inliner 25 optimization: do inlining inlineExceptionHandlers 26 optimization: inline exception handlers closelim 27 optimization: eliminate uncalled closures dce 28 optimization: eliminate dead code jvm 29 generate JVM bytecode terminal 30 The last phase in the compiler chain
ここではscalacコマンドで試しましたが、scalaコマンドでも同じことができます。
この出力されたフェーズを指定することで、Scalaコンパイラが変換している過程のASTを出力させることができます。
例えば、以下のようなコードを指定して
HelloWorld.scala
object HelloWorld { def main(args: Array[String]): Unit = { println("Hello World") } }
$ scalac -Xprint:jvm HelloWorld.scala [[syntax trees at end of jvm]] // HelloWorld.scala package <empty> { object HelloWorld extends Object { def main(args: Array[String]): Unit = scala.this.Predef.println("Hello World"); def <init>(): HelloWorld.type = { HelloWorld.super.<init>(); () } } }
コンパイルと同時に、途中のASTが表示されます。
コップ本にも、暗黙の型変換のデバッグ方法としてP.424〜425に載ってる内容ですね。
個人的には「jvm」をよく指定していますが、まあメモ程度に。