2009年7月31日金曜日

JDTのAST

EclipsePluginで、Javaソースを作成する機会があり、org.eclipse.jdt.core.dom.AST というのを使ってみました。
AST...始めは何も意識していなかったのですが、抽象構文木(abstract syntax tree)のことですねー。

ASTを使ってJavaコードを生成する事自体は、そこそこ簡単です。

ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(EMPTY.toCharArray());
CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
compilationUnit.recordModifications();

を行い、compilationUnitにクラス名やら、メソッドを追加。

ソースとして保存するときには、
IDocument document = new Document(EMPTY);
TextEdit text = compilationUnit.rewrite(document, null);
text.apply(document);
String contents = document.get();

PackageFragmentRoot root = ・・・;
IProgressMonitor monitor = ・・・;
ICompilationUnit compilationUnit = root.createCompilationUnit("test.java", contents, true, monitor);
compilationUnit.save(monitor, true);

とすればOK。

問題は、compilationUnitにどんな感じで、変数やメソッドを書いていくのか... なんですが、始めは訳分りませんでしたww
以下に例を。
//  this.{leftHand} = {rightHand}; を作成

public static void addSettingStatement(AST ast, String leftHand, String rightHand, Block methodBlock) {
Assignment assignment = ast.newAssignment();
FieldAccess leftHandExpression = ast.newFieldAccess();
ThisExpression thisExpression = ast.newThisExpression();
leftHandExpression.setExpression(thisExpression);
leftHandExpression.setName(ast.newSimpleName(leftHand));
assignment.setLeftHandSide(leftHandExpression);
assignment.setOperator(Operator.ASSIGN);
assignment.setRightHandSide(ast.newSimpleName(rightHand));
ExpressionStatement expressionStatement = ast.newExpressionStatement(assignment);
methodBlock.statements().add(expressionStatement);
}

Expressionってなんやねん! ASTからnewSimpleNameでなんか作る意味もわからん。 やたらオブジェクトいっぱい作らされるし....。

ですが、これまた偶然で構文解析についてのお勉強をする機会が別にあって、ふんわり分るようになってきました。
そんな偶然が重なるのってなんだかラッキーです。ここら辺が面白いといっている人の気持ちも少し分るようになった気もする。

ASTですが、Javaコードを作成するために使用することよりも、既存のJavaの構成を知るためにASTを見ていくことはこれからも結構ありそう。
どこを探ったら、どの情報があるのか?が分りにくくなったときには、AST Viewプラグインを使うと良さそうです。
(後で知ったため使ってないけど。)
• • •