3

我有一个名为“javaProject”的 Java 项目,它有两个类 Hello 和 ReferenceHello。

在此处输入图像描述

你好.java

package com.prosseek.test;

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

参考Hello.java

package com.prosseek.test;

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

我可以使用 Search/Java 对话框找到所有引用(或调用)Hello.world() 的方法。

在此处输入图像描述

我想以编程方式使用Search Engine. 这是我想出的代码,但是它什么也没返回。

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);      
}
  • 我的搜索代码可能有什么问题?
  • 还有其他方法可以通过编程方式在 Eclipse 插件中获取调用层次结构吗?

添加

搜索代码工作正常,问题在于我错误地使用了JavaProjectHelper.createJavaProject。我应该打开现有的 java 项目,而不是创建一个同名的项目。结果,.metadata 被破坏并且没有搜索任何内容。

使用我的新 getJavaProject 方法,现在一切正常。

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;    
}
4

2 回答 2

3

这个网站的暗示。我可以使用 CallHierarchy API。

getCallersOf() 方法

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 实用程序

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;
}

用途

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

结果

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]]]]]
于 2012-12-21T16:10:39.623 回答
2

在创建搜索范围的方法中设置断点并在调试模式下启动运行时工作台。当您在那里调用 Call Hierarchy 时,它应该停止并让您确切地看到它是如何完成的。

于 2012-12-21T00:40:47.320 回答