How to Resolve Bindings When Using Eclipse JDT ASTParser?

When using ASTParser, we often need to find type of variable in the code. This information is contains in the binding. The following code shows how to write a stand alone ASTParser to parse Java file and get the type information of variables in the code.

The target code to parse:

package test;
 
import java.util.ArrayList;
 
public class Apple {
	public static void main(String[] args) {
		ArrayList<String> al = null;
		int j =0;
		System.out.println(j);
		System.out.println(al);
	}
}

Resolve bindings using Eclipse JDT ASTParser:

package test;
 
import greenblocks.util.Util;
import java.io.File;
import java.util.Iterator;
import java.util.Map;
 
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
 
public class ASTTester {
 
	public static void main(String[] args) {
		String path ="C:\\Users\\pc\\workspace\\asttester\\src\\test\\Apple.java";
		File file = new File(path);
		String str = Util.readFileToString(file);
 
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setResolveBindings(true);
		parser.setKind(ASTParser.K_COMPILATION_UNIT);
 
		parser.setBindingsRecovery(true);
 
		Map options = JavaCore.getOptions();
		parser.setCompilerOptions(options);
 
		String unitName = "Apple.java";
		parser.setUnitName(unitName);
 
		String[] sources = { "C:\\Users\\pc\\workspace\\asttester\\src" }; 
		String[] classpath = {"C:\\Program Files\\Java\\jre1.8.0_25\\lib\\rt.jar"};
 
		parser.setEnvironment(classpath, sources, new String[] { "UTF-8"}, true);
		parser.setSource(str.toCharArray());
 
		CompilationUnit cu = (CompilationUnit) parser.createAST(null);
 
		if (cu.getAST().hasBindingsRecovery()) {
			System.out.println("Binding activated.");
		}
 
		TypeFinderVisitor v = new TypeFinderVisitor();
		cu.accept(v);		
	}
}
 
class TypeFinderVisitor extends ASTVisitor{
 
	public boolean visit(VariableDeclarationStatement node){
		for (Iterator iter = node.fragments().iterator(); iter.hasNext();) {
			System.out.println("------------------");
 
			VariableDeclarationFragment fragment = (VariableDeclarationFragment) iter.next();
			IVariableBinding binding = fragment.resolveBinding();
 
			System.out.println("binding variable declaration: " +binding.getVariableDeclaration());
			System.out.println("binding: " +binding);
		}
		return true;
	}
}

Output:

Binding activated.
------------------
binding variable declaration: ArrayList al[pos: unused][id:1]
binding: ArrayList al[pos: unused][id:1]
------------------
binding variable declaration: int j[pos: unused][id:2]
binding: int j[pos: unused][id:2]

4 thoughts on “How to Resolve Bindings When Using Eclipse JDT ASTParser?”

  1. hi i try you code and i have error


    /*
    * To change this license header, choose License Headers in Project Properties.
    * To change this template file, choose Tools | Templates
    * and open the template in the editor.
    */
    package testfile;
    import org.eclipse.jdt.core.dom.AST;
    import org.eclipse.jdt.core.dom.ASTParser;
    import org.eclipse.jdt.core.dom.ASTVisitor;
    import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
    import org.eclipse.jdt.core.dom.Block;
    import org.eclipse.jdt.core.dom.CompilationUnit;
    import org.eclipse.jdt.core.dom.Expression;
    import org.eclipse.jdt.core.dom.IMethodBinding;
    import org.eclipse.jdt.core.dom.ITypeBinding;
    import org.eclipse.jdt.core.dom.MethodDeclaration;
    import org.eclipse.jdt.core.dom.MethodInvocation;
    /**
    *
    * @author ahmed
    */
    public class Test {

    String str = "package javaproject;" // package for all classes
    + "class Dummy {" //
    + " void testSearch(String queryStr, String dateStr, SearchResources twitter1) {" //
    + " Quer query = new Quer(queryStr).unti(dateStr);" //
    + " QueryResult queryResult = twitter1.search(query);"
    //
    + " int x=1;"
    + " File file=new File();"
    + "file.x();"
    + " int y;"
    + "public class TestThread {n" +
    " public static void main(String args[]) {n" +
    " n" +
    " RunnableDemo R1 = new RunnableDemo( "Thread-1");n" +
    " R1.start();n" +
    " n" +
    " RunnableDemo R2 = new RunnableDemo( "Thread-2");n" +
    " R2.start();n" +
    " } n" +
    "}"

    + " }" //
    + "}";

    public void testrun() {
    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setSource(str.toCharArray());
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setResolveBindings(true);

    // parser.setEnvironment( // apply classpath
    // new String[] { "C:\eclipse\workspace\JavaProject\bin" }, //
    // null, null, true);
    parser.setUnitName("any_name");

    final CompilationUnit cu = (CompilationUnit) parser.createAST(null);

    cu.accept(new ASTVisitor() {

    public boolean visit(Expression anonyomousClassDeclaration) {

    System.out.println("next " + anonyomousClassDeclaration.toString());

    return true;
    }

    public boolean visit(MethodDeclaration node) {
    if (node.getName().getIdentifier().equals("testSearch")) {
    Block block = node.getBody();
    block.accept(new ASTVisitor() {
    public boolean visit(MethodInvocation node) {
    System.out.println("Name: " + node.getName());

    Expression expression = node.getExpression();
    if (expression != null) {
    System.out.println("Expr: " + expression.toString());

    ITypeBinding typeBinding = expression.resolveTypeBinding();
    if (typeBinding != null) {
    System.out.println("Type: " + typeBinding.getName());
    }
    }
    IMethodBinding binding = node.resolveMethodBinding();
    if (binding != null) {
    ITypeBinding type = binding.getDeclaringClass();
    if (type != null) {
    System.out.println("Decl: " + type.getName());
    }
    }

    return true;
    }
    });
    }
    return true;
    }
    });
    }
    }

    and i have problem in :
    Exception in thread “main” java.lang.NullPointerException
    at testfile.TypeFinderVisitor.visit(ASTTester.java:80)
    at org.eclipse.jdt.core.dom.VariableDeclarationStatement.accept0(VariableDeclarationStatement.java:266)
    in this line :
    System.out.println(“binding variable declaration: ” +binding.getVariableDeclaration());

    binding is null

  2. It turns out the problem is because I haven’t set up :

    String unitName = "Code.java";
    parser.setUnitName(unitName);

  3. Hi,

    I’ve tried to this binding tutorial, but unfortunately when I run this code, I got a NullPointerException at fragment.resolveBinding();
    So, do you have any idea on why could this happen?
    What probably did I do wrong?

Leave a Comment