VariableDeclarationFragment node resolveBindind() returns null in eclipse/jdt/ast
Asked Answered
G

3

4

I'm trying to try out eclipse jdt/ast following this article.

This is the java code as an input:

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;
        }
    }
}

With ASTView, it shows that VariableDeclarationFragment has corresponding binding. enter image description here

However, in this visitor code for VariableDeclarationFragment node, I always get null value for 4 local variables (a,b,z,i) as resolveBinding() return value.

What's wrong with this? I use eclipse indigo.

enter image description here

This is the code to get the 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
}
Gallardo answered 6/10, 2012 at 0:28 Comment(0)
S
5

This happens because of the following from the setResolveBindings docs:

Binding information is obtained from the Java model. This means that the compilation unit must be located relative to the Java model. This happens automatically when the source code comes from either setSource(ICompilationUnit) or setSource(IClassFile). When source is supplied by setSource(char[]), the location must be established explicitly by setting an environment using setProject(IJavaProject) or setEnvironment(String[], String[], String[], boolean) and a unit name setUnitName(String). Note that the compiler options that affect doc comment checking may also affect whether any bindings are resolved for nodes within doc comments.

That means you could use something like that (from your link):

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

IJavaProject javaProject = JavaCore.create(project);

and add the setProject call:

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
}

The second approach (without 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
}
Stylographic answered 9/10, 2012 at 0:1 Comment(1)
I'm using jdt/ast as a standalone java program, so I can't get an access to the IJavaProject. Thanks for the answer.Gallardo
C
0

Does this mean I have to import source codes I want to run ASTParser on in my current project?

Right now I am using ASTParser incoporating with UIMA framework. In that framework, I could get source code in char[] only. Don't know how to get their corresponding IJavaProject and UnitName, which is needed if I .setSource() to a char[].

Cowart answered 1/3, 2013 at 23:52 Comment(0)
W
0

I tried solving this using the following piece of code

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;
        }
    });
Willamina answered 2/7, 2014 at 20:51 Comment(1)
Welcome to StackOverflow, and thank you for your answer. But if it nice to provide code for solving, it is greatly appreciated in this site to explain the why and the how so that answers can be re-used later. You really should update your post to add some precisions.Diffusivity

© 2022 - 2024 — McMap. All rights reserved.