坂道で -6ページ目

坂道で

ゆるめ

アメブロにGistのソースコードを貼ろうとして、躓く。
禁止タグ厳しいね。

ググってみれば、案の定、挑戦者たちの足跡が見つかる。

一人目 AmebloにGistのソースコードを貼り付けたい!(かなり妥協)AmebloにGistのソースコードを貼り付けたい!(リベンジ)

二人目 アメブロに Gist のソースコードを貼付けたい


一人目の挑戦者は、jsファイルから、Gistコードのhtmlタグを静的に生成するWebサービスを作った。
二人目の挑戦者は、フリープラグイン化して、divタグとid属性から、動的にブログ中にGistコードを埋め込めるようにした。

凄い!どんどん楽になっている。
偉大な先人たちに感謝を!
が、
2013年現在、悲しいかな、Gistサービスの仕様変更で、どちらの手段も上手くいかない。
(一人目の方法なら、css周りをごにょごにょすればなんとか使えるけど・・・でも・・・)
二人目の方法はかなり便利だが、古いGistを表示しようとするといつまでたっても"Loading now…"・・・。
何か修正が必要だ。

で、三人目の挑戦者であるさたなべは、二人目のやり方を踏襲をしてフリープラグインを制作した。


使い方

フリープラグインを追加する

次のように、フリープラグインを追加する。 上3つのscriptタグはjqueryのロード。
何かごちゃごちゃしているのは、アメブロが標準で読み込む古いjqueryと競合しないようにするためとか。
で、4つめのscriptタグが今回用意したプラグイン。

divタグを記事へ追加する

プラグインを追加したら、後は記事へのdivタグを埋め込むだけ。 こんな感じ。
divタグのクラスをg2abにして、
中身に url@ 以後に表示したいGistのURLを書き込めばいい。
(現状、作りが甘いので、コメントとか、余計なものは入れないほうがいい)
url@の記述をやめて、data-url属性を利用する形式に変更しました。

ドヤァ

きっとしばらくは上手くGistを表示できるはず。
鬼のようにcssを弄る日々よ、さよなら!

みんなでコードを貼り付けながらIT(意識高い)系記事をどんどん書いていこう!

ちなみに

限定記事とか下書きじゃ動かないとかの、注意点諸々は別にここで書かなくてもいいよね・・・?

あとGitに詳しい人からは、
「なんでforkしたプロジェクトで偉そうに語ってるんだよ」とか言われてしまいそうだけど、 そのあたりの制作秘話についてはまた今度。
今回はクラス名の変更、親クラスの変更、インターフェースの変更について。
とりあえずサンプルコードを。

Sample3.java
  1. package info.haxahaxa.astparser.sample;
  2. import info.haxahaxa.astparser.sample.visitor.*;
  3. import info.haxahaxa.astparser.util.Envs;
  4. import info.haxahaxa.astparser.util.SourceFile;
  5. import java.io.File;
  6. import org.eclipse.core.runtime.NullProgressMonitor;
  7. import org.eclipse.jdt.core.dom.AST;
  8. import org.eclipse.jdt.core.dom.ASTParser;
  9. import org.eclipse.jdt.core.dom.ASTVisitor;
  10. import org.eclipse.jdt.core.dom.CompilationUnit;
  11. import org.eclipse.jface.text.Document;
  12. import org.eclipse.text.edits.TextEdit;
  13. /**
  14. * クラス名と,親クラスと,インターフェースを変更するサンプル
  15. *
  16. * @author satanabe1
  17. *
  18. */
  19. public class Sample3 {
  20.     private static ASTVisitor visitor = new SampleVisitor3();
  21.     public static void main(String[] arg) throws Exception {
  22.         SourceFile sourceFile = new SourceFile("src" + File.separator
  23.                 + "samples" + File.separator + "AntFileGen.java");
  24.         CompilationUnit unit;
  25.         ASTParser astParser = ASTParser.newParser(AST.JLS4);
  26.         // 以下の setBindingsRecovery setStatementsRecovery はおまじない.
  27.         // 完成しているソースコードを解析する時は呼ぶ必要ない.
  28.         // 詳しく知りたいならば,IMBのASTParser関連のドキュメントとかを参照すべき.
  29.         astParser.setBindingsRecovery(true);
  30.         astParser.setStatementsRecovery(true);
  31.         // 次の setResolveBindings と setEnvironment が重要!!
  32.         // setResolveBindings(true) をしておかないとまともに解析はできない.
  33.         // setResolveBindings をまともに機能させるために setEnvironment が必要.
  34.         astParser.setResolveBindings(true);
  35.         // setEnvironment の第一引数にはクラスパスの配列.第二引数にはソースコードを検索するパスの配列
  36.         // 第三第四については何も考えず null, true .納得いかない時はIBMのASTPa...
  37.         astParser.setEnvironment(Envs.getClassPath(), Envs.getSourcePath(),
  38.                 null, true);
  39.         // 解析対象のソースコードの入力とか
  40.         astParser.setUnitName(sourceFile.getFilePath());// なんでもいいから名前を設定しておく
  41.         astParser.setSource(sourceFile.getSourceCode().toCharArray());// 解析対象コードを設定する
  42.         unit = (CompilationUnit) astParser.createAST(new NullProgressMonitor());
  43.         unit.recordModifications();// ASTへの操作履歴のようなものを有効に
  44.         // 解析 & 変換実行
  45.         unit.accept(visitor);
  46.         // 変換結果を文字列で取得
  47.         String code = getCode(sourceFile.getSourceCode(), unit);
  48.         System.out.println(code);
  49.     }
  50.     /**
  51.      * ASTを文字列のコードに戻すメソッド
  52.      *
  53.      * @param code
  54.      *            元のコード
  55.      * @param unit
  56.      *            ASTVisitorで操作を行ったヤツ
  57.      * @return ソースコード
  58.      */
  59.     private static String getCode(String code, CompilationUnit unit) {
  60.         org.eclipse.jface.text.IDocument eDoc = new Document(code);
  61.         TextEdit edit = unit.rewrite(eDoc, null);
  62.         try {
  63.             edit.apply(eDoc);
  64.             return eDoc.get();
  65.         } catch (Exception ex) {
  66.             ex.printStackTrace();
  67.             return null;
  68.         }
  69.     }
  70. }

SampleVisitor3.java
  1. package info.haxahaxa.astparser.sample.visitor;
  2. import org.eclipse.jdt.core.dom.AST;
  3. import org.eclipse.jdt.core.dom.ASTVisitor;
  4. import org.eclipse.jdt.core.dom.MethodDeclaration;
  5. import org.eclipse.jdt.core.dom.Name;
  6. import org.eclipse.jdt.core.dom.SimpleName;
  7. import org.eclipse.jdt.core.dom.Type;
  8. import org.eclipse.jdt.core.dom.TypeDeclaration;
  9. /**
  10. * クラス名と,親クラスと,インターフェースを変更するサンプル
  11. *
  12. * @author satanabe1
  13. *
  14. */
  15. public class SampleVisitor3 extends ASTVisitor {
  16.     public boolean visit(TypeDeclaration node) {
  17.         // クラス名を変更する
  18.         setClassName(node, "HogeHoge");
  19.         // 親クラスを変更する
  20.         setSuperClass(node, "java.applet.Applet");
  21.         // インターフェースを変更する
  22.         setSuperInterfaces(node, "java.io.Serializable", "PiyoPiyo");
  23.         return super.visit(node);
  24.     }
  25.     /**
  26.      * クラス名を変更する
  27.      *
  28.      * @param node
  29.      *            変更したいクラス宣言ノード
  30.      * @param simpleClassName
  31.      *            変更したい名前
  32.      */
  33.     private void setClassName(TypeDeclaration node, String simpleClassName) {
  34.         AST ast = node.getAST();
  35.         SimpleName simpleName = ast.newSimpleName(simpleClassName);
  36.         node.setName(simpleName);
  37.     }
  38.     /**
  39.      * 親クラスを変更する
  40.      *
  41.      * @param node
  42.      *            変更したいクラス宣言ノード
  43.      * @param superClassName
  44.      *            継承したいクラス名
  45.      */
  46.     private void setSuperClass(TypeDeclaration node, String superClassName) {
  47.         AST ast = node.getAST();
  48.         Name name = ast.newName(superClassName);
  49.         Type superClassType = ast.newSimpleType(name);
  50.         node.setSuperclassType(superClassType);
  51.     }
  52.     /**
  53.      * インターフェースを変更する
  54.      *
  55.      * @param node
  56.      *            変更したいクラスノード
  57.      * @param newInterfaceNames
  58.      *            実装したいインターフェースの一覧
  59.      */
  60.     @SuppressWarnings("unchecked")
  61.     private void setSuperInterfaces(TypeDeclaration node,
  62.             String... newInterfaceNames) {
  63.         AST ast = node.getAST();
  64.         node.superInterfaceTypes().clear();// 古いインターフェースを全て削除
  65.         for (String interfaceName : newInterfaceNames) {
  66.             Name name = ast.newName(interfaceName);// 新しい名前を作って・・・
  67.             Type interfaceType = ast.newSimpleType(name);
  68.             node.superInterfaceTypes().add(interfaceType);// インターフェースのリストに追加する
  69.         }
  70.     }
  71.     /**
  72.      * 出力される無駄な情報を削減する為にメソッド宣言を削除
  73.      */
  74.     public boolean visit(MethodDeclaration node) {
  75.         node.delete();
  76.         return super.visit(node);
  77.     }
  78. }

Sample3.javaについてはSample2.javaとくらべて1文字しか変わってないので説明は省略。
だから今回はSampleVisitor3.javaについての説明だけに。

まずは29行目"public boolean visit(TypeDeclaration node)"
このメソッドは入力されたソースコード中の全てのクラス宣言に対して呼び出される。
で、諸々の変更はこのvisitメソッド内で呼び出されるsetホニャララで行われる。

void setClassName(TypeDeclaration node, String simpleClassName)
はじめはクラス名の変更メソッド。
このメソッドは至って単純。
node.getAST()をしてASTクラスのインスタンスを取得するのはお約束。
次に、ASTのインスタンスを使ってSimpleNameのインスタンスを作る。
このSimpleNameというのは"."の付かない名前程度の認識で問題ない。(info.haxahaxa...とかパッケージ付きはNGということ)
で、このSimpleNameのインスタンスをTypeDeclarationのインスタンスにsetNameしてやればいい。
これだけでクラス名が変更される。

void setSuperClass(TypeDeclaration node, String superClassName)
親クラスの変更メソッド。
このメソッドでやっている事は、
  1. 名前ノードの生成(L43)
  2. 名前ノードを使って、クラスノードの生成(L44)
  3. 生成されたクラスノードを親クラスとしてセット(L45)
の3つ。
ここでは名前はNameクラスを使っている。
SimpleNameクラスと違って"."付きの名前も扱える。便利。

void setSuperInterfaces(TypeDeclaration node, String... newInterfaceNames)
インターフェースの変更メソッド。
このメソッドでやっている事は、
  1. 既存のインターフェースを削除(L52)
  2. 名前ノードの生成(L54)
  3. 名前ノードを使って、クラスノードの生成(L55)
  4. 生成されたクラスノードをインターフェースのリストに追加(L56)
  5. 引数の数だけ2,3,4を繰り返す
の5つ。
先に紹介したsetSuperClassとほとんど変わらない。


今回の内容で覚えておくべきのポイントとしては、NameクラスとSimpleNameクラスの扱いくらいだろうか?
ASTParserでソースコードを弄る場合は、このどちらかのクラスに大変お世話になる。
今回はフィールドの削除や、メソッドの中身を削除する方法について。

例によってソースコード全体についてはここ


Sample2.java
  1. package info.haxahaxa.astparser.sample;
  2. import info.haxahaxa.astparser.Envs;
  3. import info.haxahaxa.astparser.SourceFile;
  4. import info.haxahaxa.astparser.sample.visitor.*;
  5. import java.io.File;
  6. import org.eclipse.core.runtime.NullProgressMonitor;
  7. import org.eclipse.jdt.core.dom.AST;
  8. import org.eclipse.jdt.core.dom.ASTParser;
  9. import org.eclipse.jdt.core.dom.ASTVisitor;
  10. import org.eclipse.jdt.core.dom.CompilationUnit;
  11. import org.eclipse.jface.text.Document;
  12. import org.eclipse.text.edits.TextEdit;
  13. /**
  14. * importを削除したり,メソッドを削除したり,フィールドを削除したり,javadocコメントを削除するサンプル
  15. *
  16. * @author satanabe1
  17. *
  18. */
  19. public class Sample2 {
  20.     private static ASTVisitor visitor = new SampleVisitor2();
  21.     public static void main(String[] arg) throws Exception {
  22.         SourceFile sourceFile = new SourceFile("src" + File.separator
  23.                 + "samples" + File.separator + "AntFileGen.java");
  24.         CompilationUnit unit;
  25.         ASTParser astParser = ASTParser.newParser(AST.JLS4);
  26.         // 以下の setBindingsRecovery setStatementsRecovery はおまじない.
  27.         // 完成しているソースコードを解析する時は呼ぶ必要ない.
  28.         // 詳しく知りたいならば,IMBのASTParser関連のドキュメントとかを参照すべき.
  29.         astParser.setBindingsRecovery(true);
  30.         astParser.setStatementsRecovery(true);
  31.         // 次の setResolveBindings と setEnvironment が重要!!
  32.         // setResolveBindings(true) をしておかないとまともに解析はできない.
  33.         // setResolveBindings をまともに機能させるために setEnvironment が必要.
  34.         astParser.setResolveBindings(true);
  35.         // setEnvironment の第一引数にはクラスパスの配列.第二引数にはソースコードを検索するパスの配列
  36.         // 第三第四については何も考えず null, true .納得いかない時はIBMのASTPa...
  37.         astParser.setEnvironment(Envs.getClassPath(), Envs.getSourcePath(),
  38.                 null, true);
  39.         // 解析対象のソースコードの入力とか
  40.         astParser.setUnitName(sourceFile.getFilePath());// なんでもいいから名前を設定しておく
  41.         astParser.setSource(sourceFile.getSourceCode().toCharArray());// 解析対象コードを設定する
  42.         unit = (CompilationUnit) astParser.createAST(new NullProgressMonitor());
  43.         unit.recordModifications();// ASTへの操作履歴のようなものを有効に
  44.         // 解析 & 変換実行
  45.         unit.accept(visitor);
  46.         // 変換結果を文字列で取得
  47.         String code = getCode(sourceFile.getSourceCode(), unit);
  48.         System.out.println(code);
  49.     }
  50.     /**
  51.      * ASTを文字列のコードに戻すメソッド
  52.      *
  53.      * @param code
  54.      *            元のコード
  55.      * @param unit
  56.      *            ASTVisitorで操作を行ったヤツ
  57.      * @return ソースコード
  58.      */
  59.     private static String getCode(String code, CompilationUnit unit) {
  60.         org.eclipse.jface.text.IDocument eDoc = new Document(code);
  61.         TextEdit edit = unit.rewrite(eDoc, null);
  62.         try {
  63.             edit.apply(eDoc);
  64.             return eDoc.get();
  65.         } catch (Exception ex) {
  66.             ex.printStackTrace();
  67.             return null;
  68.         }
  69.     }
  70. }

SampleVisitor2.java
  1. package info.haxahaxa.astparser.sample.visitor;
  2. import org.eclipse.jdt.core.dom.ASTVisitor;
  3. import org.eclipse.jdt.core.dom.FieldDeclaration;
  4. import org.eclipse.jdt.core.dom.ImportDeclaration;
  5. import org.eclipse.jdt.core.dom.Javadoc;
  6. import org.eclipse.jdt.core.dom.MethodDeclaration;
  7. /**
  8. * メソッドの中身を削除したり,フィールドを削除するサンプル
  9. *
  10. * @author satanabe1
  11. *
  12. */
  13. public class SampleVisitor2 extends ASTVisitor {
  14.     /**
  15.      * フィールド宣言をdelete!
  16.      */
  17.     public boolean visit(FieldDeclaration node) {
  18.         node.delete();
  19.         return super.visit(node);
  20.     }
  21.     /**
  22.      * javadocもついでにdelete!
  23.      */
  24.     public boolean visit(Javadoc node) {
  25.         node.delete();
  26.         return super.visit(node);
  27.     }
  28.     /**
  29.      * ダメ押しにimportもdelete!
  30.      */
  31.     public boolean visit(ImportDeclaration node) {
  32.         node.delete();
  33.         return super.visit(node);
  34.     }
  35.     /**
  36.      * メソッド内の処理をdelete!
  37.      */
  38.     public boolean visit(MethodDeclaration node) {
  39.         node.getBody().statements().clear();
  40.         return super.visit(node);
  41.     }
  42. }

Sample2.javaについては前回の記事にあるSample1.javaとほぼ変わらない。
変更点としては、
  1. 25行目のSampleVisitor2クラスのインスタンスを生成している
  2. 68-78行に新しいメソッドの追加
  3. 55-56行でのソースコードの標準出力への出力
の3点となっている。
新たに追加されたgetCodeメソッドのしている事をざっくり言ってしまえば、CompilationUnitを使っていじくり回された変更を、元のソースコードに適用して文字列に直した内容を返している。


で、
今回色々削除したり削除したり削除したりするコードがSampleVisitor2.javaとなっている。
見ての通り各visitメソッドは2行しかない。
基本はdeleteメソッドを呼ぶだけであっさり何もかも無くなっていく。

少しだけ違う処理をしているのは44行目の
node.getBody().statements().clear();
なんのことはない、これはListクラスのclearメソッドを呼んでいるだけ。
このあたりで難しい事は何もないはず。

ちなみにpackage宣言なんかはCompilationUnita側からじゃないといじれない。

まとめ
  delete!
  delete!!
  delete!!!
  clear!!!!!
このテーマ[Java / ASTParser]では、EclipseのASTParserという機能を利用してJavaソースコードの解析や変換の方法について、ユルク解説していく。

「ASTP・・・なんぞや?」という人は「Javaのソースコードから色々な情報を取得できるライブラリ」程度の認識でいいと思う。
もう少し詳しく知りたい場合は「Eclipse/プラグイン開発のTIPS集/ソースコードを解析するパーサASTParser」 あたりを読めばいいと思う。
セットアップ(?)の仕方は「EclipseのASTParserを単体で使う」が分かりやすい。

とりあえずサンプルコードの紹介と解説をしていく。
文字数の都合上、全てのコードをこのページに貼り付けることができない為、全体を眺めたい場合は、Githubのリポジトリの方を見て欲しい。
下に、サンプルコアとなる2つのファイル Sample1.java と SampleVisitor1.java を貼りつけている。

大雑把に言えば、Sample1.java には主にオマジナイASTParserでソースコードを解析する為の環境設定のような処理が記述されている。
そして、もう一方の SampleVisitor1.java でクラスの情報の取得を行なっている。

Sample1.java
  1. package info.haxahaxa.astparser.sample;
  2. import info.haxahaxa.astparser.Envs;
  3. import info.haxahaxa.astparser.SourceFile;
  4. import info.haxahaxa.astparser.sample.visitor.*;
  5. import java.io.File;
  6. import org.eclipse.core.runtime.NullProgressMonitor;
  7. import org.eclipse.jdt.core.dom.AST;
  8. import org.eclipse.jdt.core.dom.ASTParser;
  9. import org.eclipse.jdt.core.dom.ASTVisitor;
  10. import org.eclipse.jdt.core.dom.CompilationUnit;
  11. /**
  12. * クラス名やフィールド,メソッドの概要を表示するサンプル
  13. *
  14. * @author satanabe1
  15. *
  16. */
  17. public class Sample1 {
  18.     private static ASTVisitor visitor = new SampleVisitor1();
  19.     public static void main(String[] args) throws Exception {
  20.         SourceFile sourceFile = new SourceFile("src" + File.separator
  21.                 + "samples" + File.separator + "AntFileGen.java");
  22.         CompilationUnit unit;
  23.         ASTParser astParser = ASTParser.newParser(AST.JLS4);
  24.         // 以下の setBindingsRecovery setStatementsRecovery はおまじない.
  25.         // 完成しているソースコードを解析する時は呼ぶ必要ない.
  26.         // 詳しく知りたいならば,IMBのASTParser関連のドキュメントとかを参照すべき.
  27.         astParser.setBindingsRecovery(true);
  28.         astParser.setStatementsRecovery(true);
  29.         // 次の setResolveBindings と setEnvironment が重要!!
  30.         // setResolveBindings(true) をしておかないとまともに解析はできない.
  31.         // setResolveBindings をまともに機能させるために setEnvironment が必要.
  32.         astParser.setResolveBindings(true);
  33.         // setEnvironment の第一引数にはクラスパスの配列.第二引数にはソースコードを検索するパスの配列
  34.         // 第三第四については何も考えず null, true .納得いかない時はIBMのASTPa...
  35.         astParser.setEnvironment(Envs.getClassPath(), Envs.getSourcePath(),
  36.                 null, true);
  37.         // 解析対象のソースコードの入力とか
  38.         astParser.setUnitName(sourceFile.getFilePath());// なんでもいいから名前を設定しておく
  39.         astParser.setSource(sourceFile.getSourceCode().toCharArray());// 解析対象コードを設定する
  40.         unit = (CompilationUnit) astParser.createAST(new NullProgressMonitor());
  41.         unit.recordModifications();// ASTへの操作履歴のようなものを有効に
  42.         // 解析実行
  43.         unit.accept(visitor);
  44.     }
  45. }

SampleVisitor1.java
  1. package info.haxahaxa.astparser.sample.visitor;
  2. import info.haxahaxa.astparser.PrintUtil;
  3. import java.util.List;
  4. import org.eclipse.jdt.core.dom.ASTVisitor;
  5. import org.eclipse.jdt.core.dom.FieldDeclaration;
  6. import org.eclipse.jdt.core.dom.ITypeBinding;
  7. import org.eclipse.jdt.core.dom.IVariableBinding;
  8. import org.eclipse.jdt.core.dom.MethodDeclaration;
  9. import org.eclipse.jdt.core.dom.TypeDeclaration;
  10. import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
  11. /**
  12. * クラス名やフィールド,メソッドの概要を表示するサンプル
  13. *
  14. * @author satanabe1
  15. *
  16. */
  17. public class SampleVisitor1 extends ASTVisitor {
  18.     /**
  19.      * クラス宣言が見つかると呼ばれるメソッド
  20.      */
  21.     public boolean visit(TypeDeclaration node) {
  22.         PrintUtil.printTitle("クラス宣言");
  23.         ITypeBinding typeBinding = node.resolveBinding();// 詳細な情報をITypeBindingインスタンスを使って取得したい
  24.         ITypeBinding superClass = typeBinding.getSuperclass();// 親クラスの取得
  25.         ITypeBinding[] interfaces = typeBinding.getInterfaces();// インターフェースの取得
  26.         String className = typeBinding.getBinaryName();// クラス名の取得
  27.         int modifiers = typeBinding.getModifiers();// "public static"とかの識別子
  28.         PrintUtil.printMessage("ClassName", className);
  29.         PrintUtil.printModifiers("Modifiers", modifiers);
  30.         PrintUtil.printMessage("SuperClass", superClass.getBinaryName());
  31.         PrintUtil.printMessage("Interfaces", interfaces);
  32.         return super.visit(node);
  33.     }
  34.     /**
  35.      * フィールド宣言が見つかると呼ばれるメソッド
  36.      */
  37.     public boolean visit(FieldDeclaration node) {
  38.         PrintUtil.printTitle("フィールド宣言");
  39.         PrintUtil.printModifiers("Modifiers", node.getModifiers());
  40.         PrintUtil.printMessage("Type", node.getType().toString());
  41.         List fragments = node.fragments();
  42.         for (Object frg : fragments) {
  43.             if (frg instanceof VariableDeclarationFragment) {
  44.                 IVariableBinding variableBinding = ((VariableDeclarationFragment) frg)
  45.                         .resolveBinding();
  46.                 PrintUtil.printMessage("Name", variableBinding.getName());
  47.             }
  48.         }
  49.         return super.visit(node);
  50.     }
  51.     /**
  52.      * メソッド宣言が見つかると呼ばれるメソッド
  53.      */
  54.     public boolean visit(MethodDeclaration node) {
  55.         PrintUtil.printTitle("メソッド宣言");
  56.         PrintUtil.printMessage("MethodName", node.getName()
  57.                 .getFullyQualifiedName());
  58.         PrintUtil.printModifiers("Modifiers", node.getModifiers());
  59.         PrintUtil.printMessage("ReturnType", node.getReturnType2() + "");
  60.         PrintUtil.printMessage("Parameters", node.parameters().toString());
  61.         return super.visit(node);
  62.     }
  63. }

Sample1.java のmainメソッド内の処理で注目すべきポイントとしては、
  1. ASTParserクラスのインスタンスに対してsetResolveBindingsとかsetEnvironmentとかのメソッドで環境設定
  2. 更に前述のインスタンスに対してsetSourceメソッドで解析対象のソースコードをセット(46行目)
  3. CompilationUnitのインスタンスを取得してacceptメソッドで解析実行(50行目)
くらい。 基本的にはこの一連の処理が定型と考えていいと思う。

SampleVisitor1.java の注目すべきポイントは2つ。
  1. ASTVisitorクラスを継承(22行目)
  2. boolean visit(型名 node) メソッドの宣言  (26/45/64行目)
このクラスで宣言されている3つのvisitメソッドはいずれもASTVisitorクラスのvisitメソッドをオーバーライドしている。
ここで覚えておくべき事としては、ASTVisitorクラスのvisitメソッドをオーバーライドすることで、
visitメソッドの引数の型に該当するソースコードを解析した時、勝手にそのvisitメソッドが実行されると言うこと。
つまり、自分が解析したい構文のvisitメソッドを作ってやれば簡単に解析できる。


解析に方法についてはもっと詳しいサイトがたくさんあるので、そちらに任せる。
次回からソースコードの変換について紹介しようと思う。