VariableDeclarationFragment节点resolveBindind()在eclipse / jdt / ast中返回null

时间:2012-10-06 00:28:07

标签: java eclipse abstract-syntax-tree eclipse-jdt

我正试图在this article之后尝试eclipse jdt / ast。

这是java代码作为输入:

class Hello
{
    int hello()
    {
        int a = 0, b = 3;
        /* hello */
        {
            b = a * 3;
        }
        return a;
    }
    public static void main(String[] args)
    {   
        int z = 0, i = 3;
        /* hello */
        {
            i = z * 3;
        }
    }
}

使用ASTView,它显示VariableDeclarationFragment具有相应的绑定。 enter image description here

但是,在VariableDeclarationFragment node的访问者代码中,我总是将4个局部变量(a,b,z,i)的空值作为resolveBinding()返回值。

这有什么问题?我使用eclipse indigo。

enter image description here

这是获取AST的代码

private static CompilationUnit createCompilationUnit(String sourceFile) {
    String source = readWithStringBuilder(sourceFile);
    ASTParser parser = ASTParser.newParser(AST.JLS3); 
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setSource(source.toCharArray()); // set source
    parser.setResolveBindings(true); // we need bindings later on
    return (CompilationUnit) parser.createAST(null /* IProgressMonitor */); // parse
}

3 个答案:

答案 0 :(得分:4)

这是因为setResolveBindings文档中的以下内容:

  

从Java模型获取绑定信息。这意味着编译单元必须相对于Java模型。当源代码来自setSource(ICompilationUnit)或setSource(IClassFile)时,会自动发生这种情况。 当源由setSource(char [])提供时,必须通过使用setProject(IJavaProject) setEnvironment(String [],String [],String []设置环境来显式建立位置。 ],boolean)和单位名称setUnitName(String)。请注意,影响doc注释检查的编译器选项也可能会影响是否为doc注释中的节点解析任何绑定。

这意味着您可以使用类似的内容(来自您的链接):

IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject("someJavaProject");
project.open(null /* IProgressMonitor */);

IJavaProject javaProject = JavaCore.create(project);

并添加setProject电话:

private static CompilationUnit createCompilationUnit(String sourceFile,
        IJavaProject javaProject) {
    String source = readWithStringBuilder(sourceFile);
    ASTParser parser = ASTParser.newParser(AST.JLS3); 
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setSource(source.toCharArray()); // set source
    parser.setProject(javaProject);
    parser.setResolveBindings(true); // we need bindings later on
    return (CompilationUnit) parser.createAST(null /* IProgressMonitor */); // parse
}

第二种方法(没有setProject):

private static CompilationUnit createCompilationUnit(String sourceFile,
        String unitName) {
    String source = readWithStringBuilder(sourceFile);
    ASTParser parser = ASTParser.newParser(AST.JLS3); 
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setSource(source.toCharArray()); // set source
    String[] classpathEntries = ...;
    String[] sourcepathEntries = ...;
    parser.setEnvironment(classpathEntries, sourcepathEntries, null, true);
    parser.setUnitName(unitName);
    parser.setResolveBindings(true);
    // optional
    // parser.setBindingsRecovery(true);
    return (CompilationUnit) parser.createAST(null /* IProgressMonitor */); // parse
}

答案 1 :(得分:0)

这是否意味着我必须导入我想在当前项目中运行ASTParser的源代码?

现在我正在使用ASTParser和UIMA框架。 在该框架中,我只能在char []中获取源代码。 不知道如何获取相应的IJavaProject和UnitName,如果我.setSource()到char [],则需要它。

答案 2 :(得分:0)

我尝试使用以下代码解决此问题

protected static CompilationUnit parseStatements(String source) {
    ASTParser parser = ASTParser.newParser(AST.JLS8);
       parser.setSource(source.toCharArray());
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setResolveBindings(true);

    parser.setEnvironment( // apply classpath
            new String[] { "//home//user//Projects//SmartCopy//ASTParser_Test//bin" }, //
            null, null, true);
    parser.setUnitName("any_name");
    final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
    return cu;

}


static void newcheckVariableDeclaration(){
    String source ="package javaproject;" // package for all classes
            + "class Dummy {"
            + "int j;" //
            + "   public void add(){"
            + "int x=0,y=0;"
            + "j=x+y;\n" //
            + "   }" //
            + "}"; 

    final CompilationUnit root = parseStatements(source);
    root.accept(new ASTVisitor() {
        public boolean visit(SimpleName node) {
            System.out.println(node.toString());
            if(node.resolveBinding() == null){
                System.out.println(node.toString()+" is not declared");
            }
            else{
                System.out.println(node.toString() + " is declared");
            }
            System.out.println();
            return true;
        }
    });