JDTを使ってメソッドの呼び出し元を検索する方法
備忘録として。 eclipseとjdtを使ったメソッド呼び出し元検索のサンプルコード。
import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.equinox.app.IApplication; import org.eclipse.equinox.app.IApplicationContext; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy; import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; public class Application implements IApplication { public Object start(IApplicationContext context) throws Exception { String projectName = "sample"; String fqcn = "pkg.ClassA"; String methodName = "methodA"; IType type = findType(projectName, fqcn); IMember[] members = findMethod(type, methodName); for (IMember m : members) { CallTracer tracer = new CallTracer(m); traceCaller(tracer); tracer.trace(); // tracer.traceSimple(); } return IApplication.EXIT_OK; } private void traceCaller(CallTracer tracer) { IMember member = tracer.getTarget(); CallerUtil util = new CallerUtil(); Set<IMethod> methods = util.getCallers(member); for (Iterator<IMethod> ite = methods.iterator(); ite.hasNext();) { IMethod next = ite.next(); CallTracer c = new CallTracer(next); tracer.addCaller(c); traceCaller(c); } } private IMethod[] findMethod(IType type, String methodName) throws JavaModelException { IMethod[] methods = type.getMethods(); List<IMethod> result = new ArrayList<IMethod>(); for (IMethod method : methods) { if (method.getElementName().equals(methodName)) { result.add(method); } } return result.toArray(new IMethod[result.size()]); } private IType findType(String projectName, String fullName) throws JavaModelException { IJavaProject jp = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject(projectName)); return jp.findType(fullName); } @Override public void stop() { // TODO Auto-generated method stub } class CallerUtil { public HashSet<IMethod> getCallers(IMember member) { CallHierarchy callHierarchy = CallHierarchy.getDefault(); IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); callHierarchy.setSearchScope(scope); IMember[] members = { member }; MethodWrapper[] methodWrappers = callHierarchy.getCallerRoots(members); HashSet<IMethod> result = new HashSet<IMethod>(); for (MethodWrapper mw : methodWrappers) { MethodWrapper[] calls = mw.getCalls(new NullProgressMonitor()); result.addAll(getMethods(calls)); } return result; } private HashSet<IMethod> getMethods(MethodWrapper[] methodWrappers) { HashSet<IMethod> result = new HashSet<IMethod>(); for (MethodWrapper mw : methodWrappers) { IMethod method = toMethod(mw); if (method != null) { result.add(method); } } return result; } private IMethod toMethod(MethodWrapper methodWrappers) { IMember member = methodWrappers.getMember(); if (member.getElementType() == IJavaElement.METHOD) { return (IMethod) methodWrappers.getMember(); } else { System.out.println("IGNORE:" + member.toString()); } return null; } } class CallTracer { private IMember target; private List<CallTracer> callers; public CallTracer(IMember member) { target = member; callers = new ArrayList<CallTracer>(); } public void addCaller(CallTracer c) { callers.add(c); } public IMember getTarget() { return target; } public void trace() { trace(0); } private void trace(int idt) { printTrace(idt); for (CallTracer tracer : callers) { idt++; tracer.trace(idt); } } public void traceSimple() { traceSimple(true, 0); } public void traceSimple(boolean pltFlg, int idt) { if (pltFlg) { printTrace(idt); idt++; } if (callers.isEmpty()) { printTrace(idt); } else { for (CallTracer tracer : callers) { tracer.traceSimple(false, idt); } } } private void printTrace(int idt) { System.out.println(getIdt(idt) + " class:" + target.getParent().getElementName()); System.out.println(getIdt(idt) + "method:" + target.getElementName()); } private String getIdt(int idt) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < idt; i++) { sb.append("\t"); } return sb.toString(); } } }