3

Hello と ReferenceHello の 2 つのクラスを持つ「javaProject」という名前の Java プロジェクトがあります。

ここに画像の説明を入力

Hello.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

メソッドにブレークポイントを設定して検索範囲を作成し、ランタイム ワークベンチをデバッグ モードで起動します。そこで呼び出し階層を呼び出すと、停止し、それがどのように行われたかを正確に確認できるはずです。

于 2012-12-21T00:40:47.320 に答える