Gradle の Scala プラグインで -Xprint オプションを使用
Gradle の Scala プラグインで -Xprint オプションを試してみました。
- Gradle 1.7
-Xprint はコンパイル途中のコードを出力する Scala コンパイラのオプションで、
-Xprint:<フェーズ>
のようにコンパイルフェーズを指定して使用します。
例えば -Xprint:typer
と指定する事で implicit による暗黙変換などを処理した後のコードが出力されます。
-Xprint オプション指定方法
Gradle の Scala プラグインで -Xprint のようなオプションを指定するには下記のように compileScala.scalaCompileOptions.additionalParameters
を使います。
build.gradle 設定例 (-Xprint:typer 指定)
apply plugin: 'scala' ・・・ compileScala { scalaCompileOptions.additionalParameters = ['-Xprint:typer', ・・・] }
ここで compileScala.scalaCompileOptions.useAnt
の値によって、使用される Scala コンパイラクラスや -Xprint の出力に差が生じる点に注意が必要です。
useAnt の値 | Scala コンパイラクラス | -Xprint の出力 |
---|---|---|
true | AntScalaCompiler | gradle コマンドで -i オプションを指定すると出力される |
false | ZincScalaCompiler | 特に何もしなくても出力される |
なお、useAnt は true
がデフォルト値です。
-Xprint:typer を指定したビルド例
それでは、下記のような build.gradle とサンプルソースを使って -Xprint:typer を試してみます。
サンプルソースは http://github.com/fits/try_samples/tree/master/blog/20130928/
ビルド定義 build.gradle
apply plugin: 'scala' repositories { mavenCentral() } dependencies { compile 'org.scala-lang:scala-library:2.10.2' compile 'org.scalaz:scalaz-core_2.10:7.1.0-M3' } compileScala { scalaCompileOptions.additionalParameters = ['-Xprint:typer', '-feature'] // (1) scalaCompileOptions.useAnt = false // (2) // scalaCompileOptions.useAnt = true }
サンプルソース Sample.scala
package fits.sample import scala.language.postfixOps import scalaz._ import Scalaz._ object Sample extends App { val plus3: Int => Int = 3 + val times: Int => Int = 2 * // 2 * (3 + 4) = 14 println( 4 |> plus3 >>> times ) // (3 + 4, 2 * 5) = (7, 10) println( (4, 5) |> plus3 *** times ) // (3 + 5, 2 * 5) = (8, 10) println( 5 |> plus3 &&& times ) }
(1) useAnt = false の場合
useAnt を false
に変更した場合の gradle build
結果は下記の通りです。
(-Xprint:typer の内容が出力されます)
実行結果
> gralde build :compileJava UP-TO-DATE :compileScala [[syntax trees at end of typer]] // Sample.scala package fits.sample { import scala.language.postfixOps; import scalaz._; import scalaz.Scalaz._; object Sample extends AnyRef with App { def <init>(): fits.sample.Sample.type = { Sample.super.<init>(); () }; private[this] val plus3: Int => Int = { ((x: Int) => 3.+(x)) }; <stable> <accessor> def plus3: Int => Int = Sample.this.plus3; private[this] val times: Int => Int = { ((x: Int) => 2.*(x)) }; <stable> <accessor> def times: Int => Int = Sample.this.times; scala.this.Predef.println(scalaz.Scalaz.ToIdOps[Int](4).|>[Int](scalaz.Scalaz.ToComposeOps[Function1, Int, Int](Sample.this.plus3)(scalaz.Scalaz.function1Instance).>>>[Int](Sample.this.times))); scala.this.Predef.println(scalaz.Scalaz.ToIdOps[(Int, Int)](scala.Tuple2.apply[Int, Int](4, 5)).|>[(Int, Int)](scalaz.Scalaz.ToArrowOps[Function1, Int, Int](Sample.this.plus3)(scalaz.Scalaz.function1Instance).***[Int, Int](Sample.this.times))); scala.this.Predef.println(scalaz.Scalaz.ToIdOps[Int](5).|>[(Int, Int)](scalaz.Scalaz.ToArrowOps[Function1, Int, Int](Sample.this.plus3)(scalaz.Scalaz.function1Instance).&&&[Int](Sample.this.times))) } } :processResources UP-TO-DATE :classes :jar :assemble :compileTestJava UP-TO-DATE :compileTestScala UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test UP-TO-DATE :check UP-TO-DATE :build BUILD SUCCESSFUL
(2) useAnt = true の場合
useAnt が true
(デフォルト値) の場合の gradle build
結果は下記の通りです。
(-Xprint:typer の内容は出力されません)
実行結果1
> gralde build :compileJava UP-TO-DATE :compileScala :processResources UP-TO-DATE :classes :jar :assemble :compileTestJava UP-TO-DATE :compileTestScala UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test UP-TO-DATE :check UP-TO-DATE :build BUILD SUCCESSFUL
ここで gradle build -i
と実行すれば -Xprint:typer の内容が出力されます。
実行結果2
> gralde build -i ・・・ [ant:scalac] [[syntax trees at end of typer]] // Sample.scala [ant:scalac] package fits.sample { [ant:scalac] import scala.language.postfixOps; [ant:scalac] import scalaz._; [ant:scalac] import scalaz.Scalaz._; [ant:scalac] object Sample extends AnyRef with App { [ant:scalac] def <init>(): fits.sample.Sample.type = { [ant:scalac] Sample.super.<init>(); [ant:scalac] () [ant:scalac] }; [ant:scalac] private[this] val plus3: Int => Int = { [ant:scalac] ((x: Int) => 3.+(x)) [ant:scalac] }; [ant:scalac] <stable> <accessor> def plus3: Int => Int = Sample.this.plus3; [ant:scalac] private[this] val times: Int => Int = { [ant:scalac] ((x: Int) => 2.*(x)) [ant:scalac] }; [ant:scalac] <stable> <accessor> def times: Int => Int = Sample.this.times; [ant:scalac] scala.this.Predef.println(scalaz.Scalaz.ToIdOps[Int](4).|>[Int](scalaz.Scalaz.ToComposeOps[Function1, Int, Int](Sample.this.plus3)(scalaz.Scalaz.function1Instance).>>>[Int](Sample.this.times))); [ant:scalac] scala.this.Predef.println(scalaz.Scalaz.ToIdOps[(Int, Int)](scala.Tuple2.apply[Int, Int](4, 5)).|>[(Int, Int)](scalaz.Scalaz.ToArrowOps[Function1, Int, Int](Sample.this.plus3)(scalaz.Scalaz.function1Instance).***[Int, Int](Sample.this.times))); [ant:scalac] scala.this.Predef.println(scalaz.Scalaz.ToIdOps[Int](5).|>[(Int, Int)](scalaz.Scalaz.ToArrowOps[Function1, Int, Int](Sample.this.plus3)(scalaz.Scalaz.function1Instance).&&&[Int](Sample.this.times))) [ant:scalac] } [ant:scalac] } [ant:scalac] :compileScala (Thread[main,5,main]) - complete ・・・