找出JDT中调用方法的类型

时间:2013-01-20 19:41:13

标签: java eclipse eclipse-plugin eclipse-jdt

在此代码中,prosseek.B #bar()方法调用prosseek.SuperA#foo()。

package prosseek;

public class SuperA {
    int i = 0;
    public void foo()
    {
        System.out.println(i);
    }
}

public class B {
    public void bar()
    {
        SuperA a = new SuperA();
        a.foo();
    }
}

我需要检测bar()中调用的foo()的类型。 我使用ASTVisitor来检测MethodInvocation代码(a.foo()),但我不知道如何从中获取SuperA类型。

ICompilationUnit icu = type.getCompilationUnit();
final ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(icu);
parser.setResolveBindings(true); // we need bindings later on
CompilationUnit unit = (CompilationUnit) parser.createAST(null);

unit.accept(new ASTVisitor() {
    public boolean visit(MethodInvocation methodInvocation)
    {
        // ???

        return false;
    }
}

ADDED

我从JDT基础知识教程中得到了提示。

enter image description here

我尝试了以下代码:

IBinding binding = methodInvocation.resolveTypeBinding();
IType type = (IType)binding.getJavaElement();
if (type == null)
    return false;

但是,对于binding.getJavaElement();

的返回值,我得到null

3 个答案:

答案 0 :(得分:6)

您可能需要从 Expression 中获取类型,而不是采用 MethodInvocation 的类型。我没有对此进行测试,但这可能有所帮助。

public boolean visit(MethodInvocation node) {
    Expression exp = node.getExpression();
    ITypeBinding typeBinding = node.getExpression().resolveTypeBinding();
    System.out.println("Type: " + typeBinding.toString());
}

答案 1 :(得分:1)

您可能从以下地址获得空值:

methodInvocation.resolveTypeBinding();

因为您没有正确设置解析器。根据resolveTypeBinding的JDT文档:

“解析并返回此表达式类型的绑定。 请注意,除非在构建AST时请求绑定,否则绑定通常不可用。“ (http://goo.gl/IAUtR8

为了启用绑定,您必须在解析器上调用此方法:

parser.setBindingsRecovery(true);

答案 2 :(得分:0)

我可以使用此代码获取IType:find方法,找到ICompilationUnit,找到包含该方法的类。

我认为代码相当愚蠢,可能有一种方法可以为我提供从IMethod返回IType的方法。

public boolean visit(MethodInvocation methodInvocation)
{
    //IBinding binding = methodInvocation.resolveTypeBinding();
    IBinding binding = methodInvocation.resolveMethodBinding();
    IMethod method = (IMethod)binding.getJavaElement();
    ICompilationUnit cu = method.getCompilationUnit();
    IType type = null;
    try {
        IType[] types = cu.getTypes();
        if (types.length == 1) {
            type = types[0];
        }
        else {
            for (IType t : types)
            {
                IMethod[] methods = t.getMethods();
                for (IMethod m : methods)
                {
                    if (m == method) {
                        type = t;
                        break;
                    }
                }
                if (type != null)
                    break;
            }
        }
    } catch (JavaModelException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

ADDED

此代码可以正常使用。

public boolean visit(MethodInvocation node)
{
    String methodName = node.getName().toString();
    ITypeBinding typeBinding = node.getExpression().resolveTypeBinding();
    IType type = (IType)typeBinding.getJavaElement();

    System.out.printf("Type %s (method %s) calls %s\n", typeName, methodName, type.getFullyQualifiedName());
    return false;
}