Free tutorials for Java, Eclipse and Web programming



Follow me on twitter

5. Using the AST

The following will create an AST for each source file in your workspace and print out the name and the return type of each method using the AST.

Create a new plugin project "de.vogella.jdt.astsimple" using the "Hello world" template.

Maintain the following plugin dependencies.

			
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Astsimple Plug-in
Bundle-SymbolicName: de.vogella.jdt.astsimple;singleton:=true
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.0",
 org.eclipse.ui;bundle-version="3.4.2",
 org.eclipse.jdt.core;bundle-version="3.4.4",
 org.eclipse.core.resources;bundle-version="3.4.2",
 org.eclipse.jdt.ui;bundle-version="3.4.2"

		

To get information about the AST you can use the Visitor Pattern. This allows you to add a visitor to the AST for a specific elements. In this visitor can you capture information about the object and return it after processing the AST. Create for this the following class.

			
package de.vogella.jdt.astsimple.handler;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.MethodDeclaration;

public class MethodVisitor extends ASTVisitor {
	List<MethodDeclaration> methods = new ArrayList<MethodDeclaration>();

	@Override
	public boolean visit(MethodDeclaration node) {
		methods.add(node);
		return super.visit(node);
	}

	public List<MethodDeclaration> getMethods() {
		return methods;
	}
}

		

Add a new command "de.vogella.jdt.astsimple.GetInfo" and put it into the menu.

Create the following handler for this command.

			
package de.vogella.jdt.astsimple.handler;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
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.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;

public class GetInfo extends AbstractHandler {

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRoot root = workspace.getRoot();
		// Get all projects in the workspace
		IProject[] projects = root.getProjects();
		// Loop over all projects
		for (IProject project : projects) {
			try {
				if (project.isNatureEnabled("org.eclipse.jdt.core.javanature")) {

					IPackageFragment[] packages = JavaCore.create(project)
							.getPackageFragments();
					// parse(JavaCore.create(project));
					for (IPackageFragment mypackage : packages) {
						if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE) {
							for (ICompilationUnit unit : mypackage
									.getCompilationUnits()) {
								// Now create the AST for the ICompilationUnits
								CompilationUnit parse = parse(unit);
								MethodVisitor visitor = new MethodVisitor();
								parse.accept(visitor);

								for (MethodDeclaration method : visitor
										.getMethods()) {
									System.out.print("Method name: "
											+ method.getName()
											+ " Return type: "
											+ method.getReturnType2());
								}

							}
						}

					}
				}
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * Reads a ICompilationUnit and creates the AST DOM for manipulating the
	 * Java source file
	 * 
	 * @param unit
	 * @return
	 */

	private static CompilationUnit parse(ICompilationUnit unit) {
		ASTParser parser = ASTParser.newParser(AST.JLS3);
		parser.setKind(ASTParser.K_COMPILATION_UNIT);
		parser.setSource(unit);
		parser.setResolveBindings(true);
		return (CompilationUnit) parser.createAST(null); // parse
	}
}

		

Add the command to your menu. Run your new plugin, create a new Java project and select the command. It should print out the information about your methods in the IDE from which you started your new plugin