package edu.ucsd.arcum.interpreter.parser; import static edu.ucsd.arcum.util.StringUtil.separate; import java.util.List; import org.eclipse.jdt.core.dom.*; import edu.ucsd.arcum.interpreter.query.ASTTraverseTable; import edu.ucsd.arcum.interpreter.query.IASTVisitor; import edu.ucsd.arcum.util.Indenter; public class ASTPrinter implements IASTVisitor { private ASTTraverseTable traverseTable; // initialized after print is called private Indenter indenter; public ASTPrinter() { this.traverseTable = new ASTTraverseTable(); } public void print(CompilationUnit javaSourceUnit) { this.indenter = new Indenter(" "); traverseTable.traverseAST(javaSourceUnit, this); } public boolean visitASTNode(ASTNode node, StructuralPropertyDescriptor edge) { System.out.printf("%s", indenter.newLine()); if (isAtomic(node)) { System.out.printf("%s %s", node.toString().trim(), className(node)); return false; } System.out.printf(className(node)); if (node == null) { return false; } else { indenter.indent(); return true; } } public void afterVisitASTNodesChildren(ASTNode node) { indenter.unindent(); } public boolean beforeVisitEdge(ASTNode parent, StructuralPropertyDescriptor edge) { System.out.printf("%s", indenter.newLine()); System.out.printf("<%s>", edge.getId()); indenter.indent(); return true; } public void afterVisitEdge(ASTNode parent, StructuralPropertyDescriptor edge) { indenter.unindent(); } public boolean preVisitASTNodeList(ASTNode parent, List nodes, StructuralPropertyDescriptor edge) { if (nodes.size() == 0) { System.out.printf("%s[an empty list]", indenter.newLine()); return false; } else if (allModifiers(nodes, edge)) { System.out.printf("%s[%s]", indenter.newLine(), separate(nodes)); return false; } return true; } public void visitSimpleProperty(Object property, StructuralPropertyDescriptor edge) { System.out.printf("%s[%s] %s", indenter.newLine(), String.valueOf(property), className(property)); } // a null protected class name extractor private String className(Object obj) { if (obj == null) return "null"; else return obj.getClass().getSimpleName(); } private boolean isAtomic(ASTNode node) { return node instanceof Name || node instanceof StringLiteral || node instanceof PackageDeclaration || node instanceof Modifier || node instanceof Type; } private boolean allModifiers(List nodes, StructuralPropertyDescriptor edge) { if (!edge.getId().equals("modifiers")) { return false; } for (Object node: nodes) { if (!(node instanceof Modifier)) return false; } return true; } public void postVisitASTNodeListElement(StructuralPropertyDescriptor spd, List nodes) { // intentionally left blank } }