使用搜索引擎在Java/eclipse中实现调用层次结构(获取调用某个方法的所有方法) [英] Using Search Engine to implement call hierarchy (getting all the methods that invoke a certain method) in Java/eclipse

查看:22
本文介绍了使用搜索引擎在Java/eclipse中实现调用层次结构(获取调用某个方法的所有方法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为javaProject"的 Java 项目;它有两个类 Hello 和 ReferenceHello.

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

Hello.java

package com.prosseek.test;

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

参考Hello.java

ReferenceHello.java

package com.prosseek.test;

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

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

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

我想使用 Search Engine 以编程方式获得相同的结果.这是我想出的代码,但它什么都不返回.

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

  • 我的搜索代码可能有什么问题?
  • 是否有其他方法可以以编程方式在 Eclipse 插件中获取调用层次结构?
  • 搜索代码工作正常,问题在于我错误地使用了 JavaProjectHelper.createJavaProject.我应该打开现有的 java 项目,而不是创建一个同名的项目.结果,.metadata 被破坏了,什么也没有搜索到.

    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.

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

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

    推荐答案

    来自本网站.我可以使用 CallHierarchy API.

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

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

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

    用法

        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/eclipse中实现调用层次结构(获取调用某个方法的所有方法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆