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() void
main(*)
<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); }