3

I have a Java Project named "javaProject" which has two classes Hello and ReferenceHello.

enter image description here

Hello.java

package com.prosseek.test;

public class Hello {
    public void world()
    {
        System.out.println("Hello world");
    }
    
    public void referWorld()
    {
        world();
    }
}

ReferenceHello.java

package com.prosseek.test;

public class ReferenceHello {
    public void referWorld()
    {
        Hello h = new Hello();
        h.world();
    }
}

I can find all the methods that references (or invokes) Hello.world() using Search/Java dialog box.

enter image description here

I'd like to get the same result programmatically using Search Engine. This is the code that I came up with, however it returns nothing.

public void testIt() throws CoreException {
    String projectName = "javaProject";
    IJavaProject javaProject = JavaProjectHelper.createJavaProject(projectName);
    
    String targetMethodName = "world";
    SearchPattern pattern = SearchPattern.createPattern(
            targetMethodName, 
            IJavaSearchConstants.METHOD, 
            IJavaSearchConstants.REFERENCES,
            SearchPattern.R_CASE_SENSITIVE // <--- ????
            );
    
    boolean includeReferencedProjects = false;
    IJavaElement[] javaProjects = new IJavaElement[] {javaProject};
    IJavaSearchScope scope = SearchEngine.createJavaSearchScope(javaProjects, includeReferencedProjects); // <--- ????

    SearchRequestor requestor = new SearchRequestor() {
        @Override
        public void acceptSearchMatch(SearchMatch match)
                throws CoreException {
            System.out.println(match.getElement());
        }
    };
    SearchEngine searchEngine = new SearchEngine();
    searchEngine.search(
            pattern, 
            new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant()}, 
            scope, 
            requestor, 
            null);      
}
  • What might be wrong in my search code?
  • Is there other way to get the call hierarchy in a eclipse plugin programmatically?

ADDED

The search code works fine, the issue was with my wrong use of JavaProjectHelper.createJavaProject. I should have opened the existing java project, not creating one with the same name. As a result, .metadata was broken and nothing was searched.

With my new getJavaProject method, everything works fine now.

private IJavaProject getJavaProject(String projectName) throws CoreException
{
    IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
    IProject project= root.getProject(projectName);
    if (!project.exists()) {
        project.create(null);
    } else {
        project.refreshLocal(IResource.DEPTH_INFINITE, null);
    }
    
    if (!project.isOpen()) {
        project.open(null);
    }
    
    IJavaProject jproject= JavaCore.create(project);
    
    return jproject;    
}
Community
  • 1
  • 1
prosseek
  • 182,215
  • 215
  • 566
  • 871

2 Answers2

3

From the hint of this site. I could use the CallHierarchy API.

getCallersOf() method

package com.prosseek.asttest;

// http://www.programcreek.com/2011/07/find-all-callers-of-a-method/
import java.util.HashSet;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod; 
import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy;
import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper;

public class CallHierarchyGenerator {
public HashSet<IMethod> getCallersOf(IMethod m) {

    CallHierarchy callHierarchy = CallHierarchy.getDefault();

    IMember[] members = { m };

    MethodWrapper[] methodWrappers = callHierarchy.getCallerRoots(members);
    HashSet<IMethod> callers = new HashSet<IMethod>();
    for (MethodWrapper mw : methodWrappers) {
        MethodWrapper[] mw2 = mw.getCalls(new NullProgressMonitor());
        HashSet<IMethod> temp = getIMethods(mw2);
        callers.addAll(temp);
    }

    return callers;
}

HashSet<IMethod> getIMethods(MethodWrapper[] methodWrappers) {
    HashSet<IMethod> c = new HashSet<IMethod>();
    for (MethodWrapper m : methodWrappers) {
        IMethod im = getIMethodFromMethodWrapper(m);
        if (im != null) {
            c.add(im);
        }
    }
    return c;
}

IMethod getIMethodFromMethodWrapper(MethodWrapper m) {
    try {
        IMember im = m.getMember();
        if (im.getElementType() == IJavaElement.METHOD) {
            return (IMethod) m.getMember();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
}

findMethod utility

IMethod findMethod(IType type, String methodName) throws JavaModelException
{
    //IType type = project.findType(typeName);

    IMethod[] methods = type.getMethods();
    IMethod theMethod = null;

    for (int i = 0; i < methods.length; i++)
    {
        IMethod imethod = methods[i];
        if (imethod.getElementName().equals(methodName)) {
            theMethod = imethod;
        }
    }

    if (theMethod == null)
    {           
        System.out.println("Error, method" + methodName + " not found");
        return null;
    }

    return theMethod;
}

The usage

    CallHierarchyGenerator callGen = new CallHierarchyGenerator();

    IMethod m = findMethod(type, "world");
    Set<IMethod> methods = new HashSet<IMethod>();
    methods = callGen.getCallersOf(m);
    for (Iterator<IMethod> i = methods.iterator(); i.hasNext();)
    {
        System.out.println(i.next().toString());
    }

The result

void referWorld() {key=Lcom/prosseek/test/ReferenceHello;.referWorld()V} [in ReferenceHello [in ReferenceHello.java [in com.prosseek.test [in src [in javaTest]]]]]
void referWorld() {key=Lcom/prosseek/test/Hello;.referWorld()V} [in Hello [in Hello.java [in com.prosseek.test [in src [in javaTest]]]]]
prosseek
  • 182,215
  • 215
  • 566
  • 871
2

Set breakpoints in the methods for creating the search scope and launch your runtime workbench in Debug mode. When you invoke the Call Hierarchy there, it should stop and let you see exactly how it's done.

nitind
  • 19,089
  • 4
  • 34
  • 43