Java
AST

AST解析するためのメモ

ASTとは

抽象構文木(AST)のこと。
http://home.a00.itscom.net/hatada/c-tips/ast/ast01.html

プログラムにおけるAST

ソースコードを解析し、各ノードが葉となる木を生成する。

AST解析可能なlibrary

JavaPerser
https://github.com/javaparser/javaparser/wiki

com.sun.tools.javac.modelのlibraryを使えば、コンパイル時の中間ASTの変更も可能…??

JavaParserについてメモ

パース

ソースコードをパースするために以下のコードにてパースしCompilationUnit型へ変換する、この引数にはInputStereamやFile等指定ができる

JavaParser.parse(source);

AST変更

CompilationUnitに一度変換すれば各ノードを表すオブジェクトを取得できるので、そこから改変が可能

CompilationUnitから直接取得できるであろうノードは以下

  • ImportDeclaration
  • AnnotationDeclaration
  • PackageDecralation
  • ClassOrInterfaceDeclaration
  • EnumDeclaration

おそらくClass(またはInterface)内のノードを処理したければClassOrInterfaceDeclarationを一度取得し、改変していく。

メソッドを取得したい場合

targetclass.getMethodsByName("testMethod1")

これで名前が”testMethod1”のメソッドを表すノードMethodDeclarationのリストが取得できる。(同一の名前がある場合にはその分リストに追加される)

Modifierはprivateとかその辺をさす

また、引数付きのMethodを取得したい場合には。

//methodNameという名前で、Stringとintを引数に持つMethodが取得できる
ClassOrInterfaceDeclaration.getMethodsBySignature(String new methodName, new String[] {"String","int"});

ノードを消す

そのままremove()を呼べば消える。

名前を変える。

setName(String name)を呼ぶ。
SimpleNameオブジェクトを使って代入することもできる

初期化を変更する。

VariableDeclaratorのsetInitializerによって初期化を変更する。
引数がExpression型となっており、これはJavaParser.parseExpressionにより作成可能。

VariableDeclarator.setInitializer(JavaParser.parseExpression(content));

Classに変数を突っ込む

先ほどと同様にClassOrInterfaceDeclarationを使用する。
このオブジェクトのadd***を呼ぶと、ノードの追加と共にそのノードを表すオブジェクトを取得できる。

//private ScanSize[] aaa;を追加する
FieldDeclaration field = targetclass.addField(ScanSize[].class, "aaa", Modifier.PRIVATE);

このfieldオブジェクトのsetVariable()に、ほかで作成したVariableDeclaratorを入れれば、そのまま入る。

多分メソッドも同様に行ける、多分。

自分のソースの変数などを別のソースに突っ込む

自分のソースを取得してパース
Path selfSource = Paths.get("<ソースのPath>");
こうすることで任意の宣言などが取得できるので、あとは他ファイルに突っ込むだけ

参考

JavaParserについて詳しい記事
https://qiita.com/opengl-8080/items/50ddee7d635c7baee0ab#%E5%8F%82%E8%80%83

アノテーションプロセッサで AST 変換 - Lombok を参考にして変数の型をコンパイル時に変更
http://fits.hatenablog.com/entry/2015/01/17/172651