2

在此代码中,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;
    }
}

添加

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

在此处输入图像描述

我尝试了以下代码:

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

但是,对于 binding.getJavaElement(); 的返回值,我得到了 null;

4

3 回答 3

7

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

public boolean visit(MethodInvocation node) {
    Expression exp = node.getExpression();
    ITypeBinding typeBinding = node.getExpression().resolveTypeBinding();
    System.out.println("Type: " + typeBinding.toString());
}
于 2013-01-21T05:58:46.573 回答
1

您可能从以下位置获得空值:

methodInvocation.resolveTypeBinding();

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

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

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

parser.setBindingsRecovery(true);

于 2014-02-18T03:35:15.313 回答
0

我可以使用此代码来获取 IType:查找方法,查找 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();
    }
}

添加

这段代码适用于我。

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;
}
于 2013-01-20T19:49:49.463 回答