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: ArrayListal[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]
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
Cheers 🙂
It turns out the problem is because I haven’t set up :
String unitName = "Code.java";
parser.setUnitName(unitName);
Hi,
I’ve tried to this binding tutorial, but unfortunately when I run this code, I got a
NullPointerException
atfragment.resolveBinding();
So, do you have any idea on why could this happen?
What probably did I do wrong?