java - Java/eclipse中使用Search Engine实现调用层次结构(获取调用某个方法的所有方法)

标签 java eclipse search

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

enter image description here

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

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

enter image description here

我想使用 搜索引擎 以编程方式获得相同的结果。这是我想出的代码,但它没有返回任何内容。

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

最佳答案

来自 this site 的暗示.我可以使用 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;
}
}

查找方法实用程序

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]]]]]

关于java - Java/eclipse中使用Search Engine实现调用层次结构(获取调用某个方法的所有方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13980726/

相关文章:

Mysql:根据列中的值查找列名,在另一个表中搜索列名作为值

MySQL - 需要在 URL 表中搜索包含指定单词的 URL

eclipse - 在 Tomcat 上运行 Vaadin (maven) 示例项目时出现问题

html - 格式化用于博客发布的 Eclipse 代码片段?

java - 在 Spring 的 WebApplicationInitializer 中排序监听器

java - HTTP 传输错误 : javax.net.ssl.SSLHandshakeException

eclipse - Maven 构建与 Eclipse 构建有何不同?

c - 使用C从txt文件中获取具体数据

java - 递归调用构建二叉搜索树的方法

java - 为什么 Java 没有 EmptyQueueException?