001package eu.cqse.check.util.clang; 002 003import java.io.PrintStream; 004 005import eu.cqse.clang.CXChildVisitResult; 006import eu.cqse.clang.CXCursor; 007import eu.cqse.clang.ClangBinding; 008import eu.cqse.clang.IClangCursorVisitor; 009 010/** 011 * Visitor implementation for Clang ASTs. Prints a representation of each 012 * {@link CXCursor} to a {@link PrintStream}. 013 */ 014public class PrintVisitor implements IClangCursorVisitor { 015 016 /** 017 * Current nesting level (indentation of the output) 018 */ 019 private final int level; 020 /** 021 * Printer used to get a String representation of each {@link CXCursor}. Accepts 022 * the current cursor and its parent. 023 */ 024 private final CursorPrinter cursorPrinter; 025 /** 026 * Target stream to which we print the Strings. 027 */ 028 private final PrintStream outputStream; 029 030 /** 031 * Private constructor that allows setting the nesting level of the current 032 * cursor. 033 */ 034 private PrintVisitor(int level, CursorPrinter cursorPrinter, PrintStream outputStream) { 035 this.level = level; 036 this.cursorPrinter = cursorPrinter; 037 this.outputStream = outputStream; 038 } 039 040 /** 041 * Constructor for a {@link PrintVisitor} that traverses a Clang AST and prints 042 * a representation of each {@link CXCursor} to the given {@link PrintStream}. 043 * 044 * Use a new {@link CursorPrinter} as first parameter to get a simple 045 * {@link CXCursor}-Representation for debugging. Use {@link System#out} or 046 * {@link System#err} as second parameter for debugging. 047 */ 048 public PrintVisitor(CursorPrinter cursorPrinter, PrintStream outputStream) { 049 this.level = 0; 050 this.outputStream = outputStream; 051 this.cursorPrinter = cursorPrinter; 052 } 053 054 @Override 055 public CXChildVisitResult visit(CXCursor cursor, CXCursor parent) { 056 057 for (int i = 0; i < level; i++) { 058 outputStream.print(" "); 059 } 060 outputStream.println(cursorPrinter.getCursorRepresentation(cursor, parent)); 061 062 ClangBinding.visitChildren(cursor, new PrintVisitor(level + 1, cursorPrinter, outputStream)); 063 return CXChildVisitResult.CXChildVisit_Continue; 064 } 065 066}