How lombok works

この記事は約4分で読めます。

アノテーションさえ十分に使いこなせていないが、、javaのlombokライブラリについて調べる機会があったので自分なりにまとめてみる。

lombokは、AST変換というマジックを使ってコンパイラの変換プロセスの中で生成されたAST(抽象構文木)を操作し、アノテーションに対応するコードを差し込んでいるようだった。ソースからざっくりとした流れを追ってみる。

動作の流れ

javacの変換の流れを見てみる。

  • META-INF/servicesjavax.annotation.processing.Processorlombok.launch.AnnotationProcessorHider$AnnotationProcessorprocessが呼ばれる。processメソッドを見ると、実際の処理はcreateWrappedInstanceメソッドで生成されるオブジェクト(lombok.core.AnnotationProcessorクラス)に転送される。
  • lombok.core.AnnotationProcessorprocessメソッドからlombok.javac.apt.Processorprocessメソッドが呼ばれる。
  • その中から、lombok.javac.JavacTransformertransformが呼ばれるが、その前にRoundEnvironmentgetRootElementsメソッドで得られるjavax.lang.model.element.Elementのオブジェクトは、com.sun.tools.javac.tree.JCCompilationUnitに変換されている。
  • transformメソッドで、JCCompilationUnitのオブジェクトは.lombok.javac.JavacASTクラスでラップされ、lombok.javac.JavacTransformer$AnnotationVisitorでASTをトラバースし、lombok.javac.JavacAnnotationHandlerクラスのハンドラーを呼んで変換される。

Javac AST

非公開API?が使われている。mainメソッドを書き換えてみる。

com.sun.tools.javac.util.Listでappendしてもサイズが増えないのは何故?よくわからない。。上では、最後のBlockの初期化でJCExpressionStatementを渡している。

Eclipse AST

EclipseのJDTは、XML DOMモデルと同じ考え方の独自のDOMとASTを持っているらしい。DOMと同様な考え方で、コードブロックに任意のStatementを挿入したりすることができる。以下は、mainメソッドにHello, Worldを出力するStatementを挿入し、コンパイルして実行する例。

Manipulates AST with JDT

CompilationUnitは、コンパイル単位でソースファイルに該当する。createASTメソッドでは、ASTNodeクラスのオブジェクトが返ってくるが、CompilationUnitASTNodeクラスを継承しているためKindをK_COMPILATION_UNITに指定すればキャスト可能である。その後、ASTVisitorでASTをトラバースし、メソッド定義のブロックにSystem.out.printlnStatementを差し込んでいる。

jarファイルたち

どのクラスがどのjarに含まれているのかわかりづらかった。簡単に調べられる方法はあるのだろうか。。力技で探していった。

必要だったのは以下のjarたち。

参考リンク

コメント

タイトルとURLをコピーしました