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}