- 追加された行はこの色です。
- 削除された行はこの色です。
// 下階層用テンプレート
#topicpath
----
#contents
//ここにコンテンツを記述します。
org.eclipse.jdt.core.ICompilationUnit はパッケージエクスプローラ上のソースコード一つに対応するというべきインタフェースです。このインタフェースをパッケージエクスプローラなどからアクション経由で取得して、ソースコードの解析などを行うことができます。
**やってみる [#c600ab08]
次のサンプルコードは、Eclipseのアクションクラス(ハンドラクラス)経由でパッケージエクスプローラからICompilationUnitを取得し、そのインタフェースの実装メソッド
IJavaElement[] getChildren() throws JavaModelException;
を使って、コードを解析していきます。
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getActiveMenuSelectionChecked(event);
if (selection instanceof IStructuredSelection) {
IStructuredSelection sselection = (IStructuredSelection) selection;
Object firstElement = sselection.getFirstElement();
if (firstElement instanceof ICompilationUnit) {
ICompilationUnit unit = (ICompilationUnit) firstElement;
try {
if (!unit.isStructureKnown()) {
return null;
}
// まずは子要素を取得。取得されるのは、パッケージ宣言とか、クラス型とか
// クラスが複数定義されている場合もあるし。
IJavaElement elements[] = unit.getChildren();
for (IJavaElement javaElement : elements) {
// ↓型だったらば、ITypeにキャスト。
if (javaElement.getElementType() == IJavaElement.TYPE) {
IType type = (IType) javaElement;
// メソッド一覧を取得。
IMethod[] methods = type.getMethods();
// IMethod method = methods[methods.length - 1];
for (IMethod method : methods) {
System.out.println(method.getElementName());
}
}
}
} catch (JavaModelException e) {
e.printStackTrace();
}
}
}
return null;
}
-Sample.java
package hoge;
public class Sample {
public void setHoge(String hoge){
this.hoge = hoge;
}
private String hoge;
public String getHoge() {
return hoge;
}
}
こんなコードに対して上のハンドラを実行したところ、
setHoge
getHoge
と表示されました。
**TIPS集 [#d2b6421c]
***ソースコードのIResourceインスタンスを取得する。 [#b9940d2f]
JDT周りをやってるとIResouce系を忘れてしまいそうですが、ありました。
// ソースコードに対応するファイルのIResource
IResource resource = cu.getCorrespondingResource();
これでOKですね。
***ある要素(フィールドとか、メソッドとか)のオフセット位置を取得する [#q4860db4]
EclipseのJDTのソース見てると、ファイルの先頭からの文字数をカウントして、その場所にコード挿入するとか、割と地味ーなコードがよくあります。
それを実装する基本として、ソースの先頭からある要素(ここではメソッド)までのオフセット((基準点からの距離って訳ががよい?))位置を取得してみます。解析対象のソースは以下の通りです。
-Sample.java
package hoge;
public class Sample {
public void setHoge(String hoge){ <-このメソッドの「p」の位置は、先頭から38文字目。
this.hoge = hoge;
} <-また「p」前の位置からこのカッコ終わりまでの長さは、56文字
private String hoge;
public String getHoge() { <-このメソッドの「p」の位置は、先頭から121文字目。
return hoge;
} <-また「p」前の位置からこのカッコ終わりまでの長さは、43文字
}
オフセットを取得するコードは以下の通り。
public Object execute(ExecutionEvent event) throws ExecutionException {
--- 先と同じなので、省略 ---
if (firstElement instanceof ICompilationUnit) {
ICompilationUnit unit = (ICompilationUnit) firstElement;
try {
if (!unit.isStructureKnown()) {
return null;
}
IJavaElement elements[] = unit.getChildren();
for (IJavaElement javaElement : elements) {
if (javaElement.getElementType() == IJavaElement.TYPE) {
IType type = (IType) javaElement;
IMethod[] methods = type.getMethods();
for (IMethod method : methods) {
ISourceRange sourceRange = method
.getSourceRange();
int offset = sourceRange.getOffset();
System.out.println(offset);
}
}
}
} catch (JavaModelException e) {
e.printStackTrace();
// TODO: handle exception
}
}
return null;
}
この通り、IMethod method を取得して、そのインスタンスに対し
ISourceRange sourceRange = method.getSourceRange();
int offset = sourceRange.getOffset();
とすることでオフセット位置を取得することができます。ちなみに実行結果は、
38
121
となりました。
またそのメソッドの長さ(オフセット位置から、そのメソッドの終わりまでの文字数)は、
int length = sourceRange.getLength();
とやって取得できます。実行結果は、
56
43
です。これでメソッド終わり場所のオフセット位置なども取得できますね。
**関連リンク [#w3f6351b]
-Eclipse/プラグイン開発のTIPS集/Javaプロジェクトを操作する 後半でちょっと出てきます。主はIJavaElementの話ですね。
-Eclipse/プラグイン開発のTIPS集/ソースコードを解析するパーサASTParser おもにASTParserとVisitorの話ですが、ICompilationUnit を起点に話が始まります。
----
この記事は
#vote(おもしろかった,そうでもない)
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}