4

我正在尝试在这篇文章之后尝试 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有相应的绑定。 在此处输入图像描述

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

这有什么问题?我使用日食靛蓝。

在此处输入图像描述

这是获取 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
}
4

3 回答 3

5

发生这种情况是因为setResolveBindings文档中的以下内容:

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

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

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
}
于 2012-10-09T00:01:03.107 回答
0

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

现在我正在使用与 UIMA 框架结合的 ASTParser。在那个框架中,我只能在 char[] 中获得源代码。不知道如何获取它们对应的 IJavaProject 和 UnitName,如果我将 .setSource() 设置为 char[],则需要这些。

于 2013-03-01T23:52:33.593 回答
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;
        }
    });
于 2014-07-02T20:51:11.893 回答