Groovyを勉強したい人に贈る、astprintコマンド
今ごろ言うな、って話かもしれませんが、自分で2年ほど前にこっそり作っていて最高に便利だと思っているコマンド「astprint」を紹介します。
astprintの内容は以下のようにシェルスクリプトです。
#!/bin/sh groovy -e 'groovy.inspect.swingui.AstNodeToScriptAdapter.main(args)' $*
やってることは"こちら"で紹介したAstNodeToScriptAdapterを呼んでるだけです。以下ようにコンパイルの途中経過が標準出力にテキストで出力されるので簡単に見れます。本当便利です。
% cat hoge.groovy cat hoge.groovy trait FileNameIsHogeHoge { @groovy.transform.ForceOverride String getPath() { return "hogehoge" } } class MyFile extends File implements FileNameIsHogeHoge { MyFile(String fileName) { super(fileName) } } f = new MyFile("/tmp/file.txt") assert f.getPath() == "hogehoge" % astprint hoge.groovy 4 astprint hoge.groovy 4 f = new MyFile('/tmp/file.txt') assert f.getPath() == 'hogehoge' : null public class script1397699411969 extends groovy.lang.Script { public script1397699411969() { } public script1397699411969(groovy.lang.Binding context) { super.setBinding(context) } public static void main(java.lang.String[] args) { org.codehaus.groovy.runtime.InvokerHelper.runScript(script1397699411969, args) } public java.lang.Object run() { f = new MyFile('/tmp/file.txt') assert f.getPath() == 'hogehoge' : null } } @groovy.transform.Trait abstract interface public class FileNameIsHogeHoge extends java.lang.Object { @groovy.transform.ForceOverride @org.codehaus.groovy.transform.trait.Traits$Implemented abstract public java.lang.String getPath() { } } public class MyFile implements FileNameIsHogeHoge extends java.io.File { public MyFile(java.lang.String fileName) { super(fileName) } } abstract public static class FileNameIsHogeHoge$Trait$Helper extends java.lang.Object { public static void $init$(FileNameIsHogeHoge $self) { } public static void $static$init$(java.lang.Class<FileNameIsHogeHoge> $static$self) { } @groovy.transform.ForceOverride public static java.lang.String getPath(FileNameIsHogeHoge $self) { return 'hogehoge' } }
これで見るとtraitは@groovy.transform.Trait指定になってるんですねー。4はコンパイルのフェイズで、以下の意味があります。
数字 | シンボル | 説明 |
---|---|---|
1 | INITIALIZATION | ファイルを開いたり |
2 | PARSING | 字句・構文解析、ANTLRのAST構築 |
3 | CONVERSION | CSTからASTへの変換 |
4 | SEMANTIC_ANALYSIS | ASTの意味解析と解明 |
5 | CANONICALIZATION | ASTの補完 |
6 | INSTRUCTION_SELECTION | クラス生成(フェーズ1) |
7 | CLASS_GENERATION | クラス生成(フェーズ2) |
8 | OUTPUT | クラスをファイルに出力 |
9 | FINALIZATION | 後始末 |
9 | ALL | 後始末まですべて実行 |
groovyConsoleでも同じ内容が表示できますが、コマンドラインからできるのも大変便利です。
traitについては7ぐらいにするともっと展開された結果になりますが、バイトコード生成レベルではなく、かなりソースコードに近い側で展開処理してるようで参考になます。