Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use the java Eclipse Abstract Syntax Tree in a project outside Eclipse? (ie not an eclipse plugin)

Tags:

How can I use the java Eclipse Abstract Syntax Tree in a project outside Eclipse? (ie not an eclipse plugin)

All the Eclipse AST examples that I've seen are for eclipse plugins. Is there a way (ie an example) of a project that uses the eclipse AST for a non-eclipse project.

like image 428
hawkeye Avatar asked Jun 08 '09 12:06

hawkeye


2 Answers

Below is the code I used to do this given a Java 1.5 file. I'm very new to this and spent today browsing around, and trying things out to get the code below working.

public void processJavaFile(File file) {     String source = FileUtils.readFileToString(file);     Document document = new Document(source);     ASTParser parser = ASTParser.newParser(AST.JLS3);     parser.setSource(document.get().toCharArray());     CompilationUnit unit = (CompilationUnit)parser.createAST(null);     unit.recordModifications();      // to get the imports from the file     List<ImportDeclaration> imports = unit.imports();     for (ImportDeclaration i : imports) {         System.out.println(i.getName().getFullyQualifiedName());     }      // to create a new import     AST ast = unit.getAST();     ImportDeclaration id = ast.newImportDeclaration();     String classToImport = "path.to.some.class";     id.setName(ast.newName(classToImport.split("\\.")));     unit.imports().add(id); // add import declaration at end      // to save the changed file     TextEdit edits = unit.rewrite(document, null);     edits.apply(document);     FileUtils.writeStringToFile(file, document.get());      // to iterate through methods     List<AbstractTypeDeclaration> types = unit.types();     for (AbstractTypeDeclaration type : types) {         if (type.getNodeType() == ASTNode.TYPE_DECLARATION) {             // Class def found             List<BodyDeclaration> bodies = type.bodyDeclarations();             for (BodyDeclaration body : bodies) {                 if (body.getNodeType() == ASTNode.METHOD_DECLARATION) {                     MethodDeclaration method = (MethodDeclaration)body;                     System.out.println("name: " + method.getName().getFullyQualifiedName());                 }             }         }     } } 

This requires the following libraries:

commons-io-1.4.jar org.eclipse.jdt.core_xxxx.jar org.eclipse.core.resources_xxxx.jar org.eclipse.core.jobs_xxxx.jar org.eclipse.core.runtime_xxxx.jar org.eclipse.core.contenttype_xxxx.jar org.eclipse.equinox.common_xxxx.jar org.eclipse.equinox.preferences_xxxx.jar org.eclipse.osgi_xxxx.jar org.eclipse.text_xxxx.jar 
like image 53
kfox Avatar answered Jan 12 '23 10:01

kfox


According to this old article, you should be able to call AST parser independently of your application context (eclipse plugin or not).

ASTParser parser = ASTParser.newParser(AST.JLS2); parser.setSource("".toCharArray()); CompilationUnit unit = (CompilationUnit) parser.createAST(null);  unit.recordModifications(); AST ast = unit.getAST();  

alt text
(source: ibm.com)


From this bug entry:

ASTParser in 3.0 can be used in another standalone program to create Eclipse ASTs without actually running Eclipse. As the documentation says:

  char[] source = ...;   ASTParser parser = ASTParser.newParser(AST.JLS2);  // handles JLS2 (J2SE 1.4)   parser.setSource(source);   CompilationUnit result = (CompilationUnit) parser.createAST(null); 

Hence this thread attempts to parse a very short java source:

import org.eclipse.jdt.core.dom.*; import org.eclipse.jface.text.Document; import org.eclipse.text.edits.TextEdit;  public class Test{  public static void main(String[] args){  Test t= new Test();  t.runtest(); }   void runtest(){   Document doc = new Document("import java.util.List;\nclass X {}\n");   ASTParser parser = ASTParser.newParser(AST.JLS3);   parser.setResolveBindings(true);   parser.setSource(doc.get().toCharArray());   CompilationUnit cu = (CompilationUnit) parser.createAST(null);   cu.recordModifications();   AST ast = cu.getAST();   ImportDeclaration id = ast.newImportDeclaration();   id.setName(ast.newName(new String[] {"java", "util", "Set"}));   cu.imports().add(id); // add import declaration at end   TextEdit edits = cu.rewrite(doc, null);  }  } 
like image 38
VonC Avatar answered Jan 12 '23 10:01

VonC