Java Parserの使い方
Java Parserのインストール方法、使用方法を説明する。
Keywords
- Java
Contents
- 1. Java Parserとは
- 2. 環境構築
- 2-1. 前提
- 2-2. build.gradleにjavaparser-symbol-solver-coreを追加して、Gradleをリフレッシュ
- 3. 動作確認
- 4. Javaファイル(クラス)を作成してパースする
- 4-1. Personクラスを作成
- 4-2. Personクラスをパース
- 5. 抽象構文木に対して、処理を追加する。
- 6. Java Parserのユースケース
- 7. その他
- 8. 参考資料
Java Parserとは
Javaの構文をパースして、抽象構文木を作成するライブラリ。抽象構文木のそれぞれのノードに対して、処理を追加できる。
MyBatis GeneratorやLettuceでも使用されているライブラリ。
環境構築
前提
- IntelliJ IDEA
- Gradle
※IntelliJ IDEA + Gradleでプロジェクト作成方法がわからない場合は下記を参考にしてください。
IntelliJ & GradleでJavaプロジェクトを作成する
build.gradleにjavaparser-symbol-solver-coreを追加して、Gradleをリフレッシュ
javaparser-symbol-solver-coreを追加
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'com.github.javaparser', name: 'javaparser-symbol-solver-core', version: '3.13.3'
}
Gradleをリフレッシュ
動作確認
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
public class Main {
public static void main(String[] args){
String code = "class A {}";
CompilationUnit cu = StaticJavaParser.parse(code);
System.out.println(cu);
}
}
Javaファイル(クラス)を作成してパースする
Personクラスを作成
/**
* This is a target class
*/
public class Person {
private String name;
private int age;
public void sleep(){
System.out.println("zzz");
}
public void introduce(){
System.out.println("I am " + this.name);
}
public void sayHi(String whom){
System.out.println("Hello " + whom);
}
// this method must not be used.
@Deprecated
public void xxx(){
}
}
Personクラスをパース
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import java.io.File;
import java.io.FileNotFoundException;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("./src/main/java/Person.java");
CompilationUnit cu = StaticJavaParser.parse(file);
System.out.println(cu);
}
}
標準出力をみるだけじゃわからないが、debugでcuのchildNodesをたどるとパースされていることが確認できる。
抽象構文木に対して、処理を追加する。
CompilationUnitはacceptメソッドを持っており、VoidVisitorインターフェースかGenericVisitorインターフェースを受け取ることができる。
ここでは、VoidVisitorインターフェースを実装したVoidVisitorAdapterを継承したものをacceptに渡してみる。
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.comments.LineComment;
import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import java.io.File;
import java.io.FileNotFoundException;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("./src/main/java/Person.java");
CompilationUnit cu = StaticJavaParser.parse(file);
VoidVisitor<?> visitor = new SomeVisitor();
cu.accept(visitor, null);
}
private static class SomeVisitor extends VoidVisitorAdapter<Void> {
@Override
public void visit(MarkerAnnotationExpr md, Void arg) {
super.visit(md, arg);
System.out.println("annotation: " + md.getName());
}
@Override
public void visit(MethodDeclaration md, Void arg) {
super.visit(md, arg);
System.out.println("method: " + md.getName());
}
@Override
public void visit(Modifier md, Void arg) {
super.visit(md, arg);
System.out.println("modifier: " + md.toString());
}
@Override
public void visit(JavadocComment md, Void arg) {
super.visit(md, arg);
System.out.println("javadoc: " + md.toString());
}
@Override
public void visit(LineComment md, Void arg) {
super.visit(md, arg);
System.out.println("linecomment: " + md.toString());
}
}
}
Java Parserのユースケース
今のところ、レビュー時によく指摘されるようなことを事前に検出できるようなプログラムの作成の時に便利かもしれない。
その他
PHPの場合はPHP-ParserでPHPファイルをパースできます。
参考資料
- 公式 https://javaparser.org/
- ドキュメント https://leanpub.com/javaparservisited
- ドキュメントで使用されているソースコード https://github.com/javaparser/javaparser-visited