Eclipseのプラグイン開発のJDTでクラスやメソッドを検索する方法について。
SearchEngineを使用すると、ワークスペースやプロジェクト内のクラスやメソッド等(の参照箇所や定義箇所)を検索することが出来る。
import org.eclipse.jdt.core.search.SearchEngine;
SearchEngineを使って検索する例。
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.core.search.SearchMatch; import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor;
public void search(IProgressMonitor monitor) {
// 検索条件
SearchPattern pattern = createSearchPattern();
// 検索対象ドキュメント(ファイルの種類)?
SearchParticipant[] participants = { SearchEngine.getDefaultSearchParticipant() };
// 検索範囲
IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
// IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject });
// 検索結果の処理
SearchRequestor requestor = new SearchRequestor() {
@Override
public void acceptSearchMatch(SearchMatch match) throws CoreException {
IJavaElement element = (IJavaElement) match.getElement();
// 見つかった箇所を表示
System.out.printf("%s %d,%d\n", element.getElementName(), match.getOffset(), match.getLength());
}
};
// 検索の実行
try {
new SearchEngine().search(pattern, participants, scope, requestor, monitor);
} catch (CoreException e) {
e.printStackTrace();
}
}
SearchPatternで検索条件を指定する。詳細は後述。
IJavaSearchScopeで検索範囲を指定する。
SearchEngineのsearchメソッドを呼び出すことにより、検索が実行される。
検索条件に合致するものが見つかると、SearchRequestorのacceptSearchMatchメソッドが呼ばれる。
SearchMatchのgetElement()で、見つかった場所(ITypeやIMethod)が取得できる。
SearchMatchのgetOffset()やgetLength()で、見つかった位置を取得できる。
SearchPatternは、検索条件を指定する為のクラス。
import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.SearchPattern;
SearchPatternのインスタンスは、SearchPattern#createPattern()メソッドを使って生成する。
クラスやメソッドの使用箇所(参照されている場所)を検索する為のパターンの例。
private SearchPattern createSearchPattern() {
IJavaElement element = 〜; // 使われている箇所を知りたいクラス(IType)やメソッド(IMethod)
int limitTo = IJavaSearchConstants.REFERENCES; // 参照箇所を検索
int matchRule = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH;
return SearchPattern.createPattern(element, limitTo, matchRule);
}
IJavaElementを使わずに、文字列で指定することも出来る。
private SearchPattern createSearchPattern() {
// クラスを探す場合
String pattern = "com.example.modelgen.dmdl.model.SalesDetail";
int searchFor = IJavaSearchConstants.TYPE;
// メソッドを探す場合
// String pattern = "com.example.modelgen.dmdl.model.SalesDetail.getSalesDateTime()";
// int searchFor = IJavaSearchConstants.METHOD;
int limitTo = IJavaSearchConstants.REFERENCES; // 参照箇所を検索
int matchRule = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH;
return SearchPattern.createPattern(pattern, searchFor, limitTo, matchRule);
}
メソッドを探す場合、クラス名を記述せずにメソッド名だけ記述したり、引数や戻り値の型を指定することも出来る。
戻り値の型は、(先頭でなく)末尾に記述する。
引数部分に「*」を記述すると、何でもよいことになるようだ。
java.lang.Runnable.run() voidmain(*)<String>toArray(String[]) private SearchPattern createSearchPattern() {
String pattern = "getOrder() java.util.List<java.lang.String>"; // 戻り型がList<String>で、メソッド名がgetOrderで、引数は無し
int searchFor = IJavaSearchConstants.METHOD;
int limitTo = IJavaSearchConstants.DECLARATIONS; // 定義箇所を検索
int matchRule = SearchPattern.R_CASE_SENSITIVE;
return SearchPattern.createPattern(pattern, searchFor, limitTo, matchRule);
}
private SearchPattern createSearchPattern() {
String pattern = "com.asakusafw.vocabulary.model.Key"; // アノテーション名
int searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
int limitTo = IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE; // アノテーションが使われている箇所を検索
int matchRule = SearchPattern.R_CASE_SENSITIVE;
return SearchPattern.createPattern(pattern, searchFor, limitTo, matchRule);
}
複数の条件を同時に指定することも出来る。
private SearchPattern createSearchPattern() {
SearchPattern pattern1 = 〜;
SearchPattern pattern2 = 〜;
return SearchPattern.createOrPattern(pattern1, pattern2);
}