task定義におけるgradleの構文を理解する

2018年7月13日

Understanding the groovy syntax in a gradle task definitionの翻訳。

Contents

質問

GradleとGroobyは初めてですが、gradleのタスクの定義のときにgroovyでは何が起こっているのか知りたいんです。

task hello  { 
   println "helloタスクを設定しますよ" 
   doLast {
     println "こんにちは" 
   }
}

書籍「Gradle In Action」によれば、task hello {}というのは、groovyのProjectインターフェースにあるtask()というメソッドの呼び出しだといいます。 77ページを見ると、Projectインターフェースには4つのメソッドがありますね。

task(args: Map<String,?>, name:String)
task(args: Map<String,?>, name:String, c:Closure)
task(name: String)
task(name: String, c:Closure)

{}がクロージャを示すことはわかってます。

わからないことは、どうやってgroovyはtask hello {}の中のhelloを解釈するんでしょう?
https://stackoverflow.com/a/25592665/438319によれば、
groovyコンパイラプラグインがあって、それがtask hello {}をtask(‘hello’, {})に変換するんだというんです。

質問としては、

  • この変換を行うGradle Groovyコンパイラプラグインの情報はどこにあるんでしょう?

  • GradleのスクリプトはGroovyのプログラムであるという主張は、技術的に間違いですよね?なぜなら、GradleはGroovy言語を拡張しているからです。

  • 何らかの方法はあるんでしょうか?Gradleのコマンドがコンパイラプラグインによって変換された後のGroovyのコードを表示する方法です。

答え

GradleはAST変換をつかって、Groovyの構文を拡張してます。
あなたのいったtask定義構文というのは、Gradleが適用しているものの一つにすぎません。
この変換の実装はここで見ることができます。
具体的な質問についてですが、

  • Gradleが適用している個別の変換については、具体的なものはどこにも文書化されていません、私の知る限りでは。しかし、上にあげたリンクのパッケージ中の他のクラスについては見れるかもしれません。

  • Gradleスクリプトのサポートするものは、Groovy構文のスーパーセットです。正当なGroovyのコードであれば、Gradleでも正当です。が、Gradleのスクリプトは、必ずしもデフォルトのGroovyの正当なコードではなく、また典型的には正当ではありません。

  • 等価なGroovyコードを得る方法はありません。なぜなら、これらは実際には、メモリ内での抽象構文木の操作だからです。