Groovy 1.6以前でASTを構築
Groovy 1.6以前のバージョンでは、コード上で抽象構文木(Abstract Syntax Trees: AST)を構築する方法はひとつしかありませんでした。ASTNodeのサブクラスのコンストラクタを使う方法です。
これは文字列 'Hello' を返却するコードブロックを構築している例です。これの使用例としては単純に 'Hello' を返却するメソッド本体を実装といったものになるでしょう。
利点
- ドキュメントが整いました Javadoc/Groovydoc
- Javaからの実行がサポートされるようになりました
- すべてのGroovyバージョンでサポートされています
- いくつかのIDEでコード補完とパラメータの検索がサポートされました
欠点
- どんなASTを書くべきか決めるのが難しい
- 冗長 - 作成したソースとはやり取りしません
- 壊れやすい - ASTはメジャーリリース間で変更する必要があります
- 作者はASTが特にコンパイル時にどのように見えるかを知らなければなりません
Groovy 1.7でASTを構築
Groovy 1.7での3つの新しいAST構築方法をご紹介します。
- 文字列から
- コードから
- DSLのような仕様から
AstBuilder.buildFromString
AstBuilderオブジェクトはGroovyソースコード上の文字列からASTを構築するAPIを提供しています。buildFromStringメソッドを使用するオリジナルの例はこちらです。
利点
- 作者にASTNodeのサプタイプが何であるか理解していることを要求しません
- 作者にコンパイル時を対象とすることを許可します
- 生成されたソースコードとやり取りします
- 頑強 - リリースによりASTが更新されても変更しなくてもよい
欠点
- IDEでは構文や文法をチェックできません
- IDEでは文字列をリファクタリングできません
- フィールド宣言に対するASTのように、いくつかのエンティティは作成されません
AstBuilder.buildFromCode
AstBuilderオブジェクトはGroovyソースコードからASTを構築するAPIを提供しています。buildFromCodeメソッドを使用するオリジナルの例はこちらです。
利点
- 生成されるコードとのやり取りが明白です
- 作者にASTNodeのサプタイプが何であるか理解していることを要求しません
- 作者にコンパイル時を対象とすることを許可します
- 頑強 - リリースによりASTが更新されても変更しなくてもよい
- IDEがクロージャ内での構文チェックとリファクタリングをサポートします
欠点
- フィールド宣言に対するASTのように、いくつかのエンティティは作成されません
- buildFromCodeは左から実行されます。これを確かめる一番よい方法は、次のコードを実行してみることです。
むしろローカル変数を持つよりもAstBuilder型のフィールドを持つ。
AstBuilder.buildFromSpec
AstBuilderオブジェクトはDSL風のASTを構築するAPIを提供しています。buildFromSpecメソッドを使用するオリジナルの例はこちらです。
利点
- AST構築プロセス実行中に実行される条件(もしくはGroovyコード)を許可します。
- どんなASTNodeサブタイプの生成も許可されます。
- 完全に文書化されており、非常に沢山のテストケースが用意されています。
欠点
- どんなASTを書くべきか決めるのが難しい
- 冗長 - 作成したソースとはやり取りしません
- 壊れやすい - ASTはメジャーリリース間で変更する必要があります
- 作者はASTが特にコンパイル時にどのように見えるかを知らなければなりません
一番いい方法はいくつかのASTビルダーを組み合わせることです。例えば、次のメソッドを考えてみましょう。
メソッド宣言するのにbuildFromSpecを使うのが一番よいでしょう、そして本体にはbuildFromCodeを使うのがよいでしょう。
その他のリソース
Groovyで書かれたテストケースは最高のリソースです。
もっと多くの例はGEP-2にて見つかります。オリジナルの提案はhttp://docs.codehaus.org/display/GroovyJSR/GEP+2+-+AST+Builder+Supportです。
例と質問はgroovy-userとgroovy-devのメーリングリストで見つかります。