/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.lang.java.ast; import java.io.IOException; import java.io.PrintWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; public class DumpFacade extends JavaParserVisitorAdapter { private PrintWriter writer; private boolean recurse; public void initializeWith(Writer writer, String prefix, boolean recurse, JavaNode node) { this.writer = writer instanceof PrintWriter ? (PrintWriter) writer : new PrintWriter(writer); this.recurse = recurse; this.visit(node, prefix); try { writer.flush(); } catch (IOException e) { throw new RuntimeException("Problem flushing PrintWriter.", e); } } @Override public Object visit(JavaNode node, Object data) { dump(node, (String) data); if (recurse) { return super.visit(node, data + " "); } else { return data; } } private void dump(JavaNode node, String prefix) { // // Dump format is generally composed of the following items... // // 1) Dump prefix writer.print(prefix); // 2) JJT Name of the Node writer.print(node.toString()); // // If there are any additional details, then: // 1) A colon // 2) The Node.getImage() if it is non-empty // 3) Extras in parentheses // // Standard image handling String image = node.getImage(); // Special image handling (e.g. Nodes with normally null images) if (node instanceof ASTBooleanLiteral) { image = String.valueOf(((ASTBooleanLiteral) node).isTrue()); } else if (node instanceof ASTPrimaryPrefix) { ASTPrimaryPrefix primaryPrefix = (ASTPrimaryPrefix) node; String result = null; if (primaryPrefix.usesSuperModifier()) { result = "super"; } else if (primaryPrefix.usesThisModifier()) { result = "this"; } if (image != null) { result += "." + image; } image = result; } else if (node instanceof ASTPrimarySuffix) { ASTPrimarySuffix primarySuffix = (ASTPrimarySuffix) node; if (primarySuffix.isArrayDereference()) { if (image == null) { image = "["; } else { image = "[" + image; } } } // Extras List<String> extras = new ArrayList<>(); collectModifiers(node, extras); // Standard Dimensionable extras if (node instanceof Dimensionable) { Dimensionable dimensionable = (Dimensionable) node; if (dimensionable.isArray()) { StringBuilder extra = new StringBuilder("array"); for (int i = 0; i < dimensionable.getArrayDepth(); i++) { extra.append('['); } extras.add(extra.toString()); } } // Other extras if (node instanceof ASTArguments) { extras.add(String.valueOf(((ASTArguments) node).getArgumentCount())); } else if (node instanceof ASTAssignmentOperator) { extras.add(((ASTAssignmentOperator) node).isCompound() ? "compound" : "simple"); } else if (node instanceof ASTClassOrInterfaceBodyDeclaration) { if (((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) { extras.add("anonymous inner class"); } if (((ASTClassOrInterfaceBodyDeclaration) node).isEnumChild()) { extras.add("enum child"); } } else if (node instanceof ASTBlock) { if (((ASTBlock) node).containsComment()) { extras.add("contains comment"); } } else if (node instanceof ASTClassOrInterfaceDeclaration) { extras.add(((ASTClassOrInterfaceDeclaration) node).isInterface() ? "interface" : "class"); if (((ASTClassOrInterfaceDeclaration) node).isNested()) { extras.add("nested"); } } else if (node instanceof ASTConditionalExpression) { if (((ASTConditionalExpression) node).isTernary()) { extras.add("ternary"); } } else if (node instanceof ASTConstructorDeclaration) { extras.add(String.valueOf(((ASTConstructorDeclaration) node).getParameterCount())); if (((ASTConstructorDeclaration) node).containsComment()) { extras.add("contains comment"); } } else if (node instanceof ASTExplicitConstructorInvocation) { extras.add(String.valueOf(((ASTExplicitConstructorInvocation) node).getArgumentCount())); if (((ASTExplicitConstructorInvocation) node).isThis()) { extras.add("this"); } if (((ASTExplicitConstructorInvocation) node).isSuper()) { extras.add("super"); } } else if (node instanceof ASTFormalParameter) { if (((ASTFormalParameter) node).isVarargs()) { extras.add("varargs"); } } else if (node instanceof ASTFormalParameters) { extras.add(String.valueOf(((ASTFormalParameters) node).getParameterCount())); } else if (node instanceof ASTIfStatement) { if (((ASTIfStatement) node).hasElse()) { extras.add("has else"); } } else if (node instanceof ASTImportDeclaration) { if (((ASTImportDeclaration) node).isImportOnDemand()) { extras.add("on demand"); } if (((ASTImportDeclaration) node).isStatic()) { extras.add("static"); } } else if (node instanceof ASTInitializer) { extras.add(((ASTInitializer) node).isStatic() ? "static" : "nonstatic"); } else if (node instanceof ASTLiteral) { ASTLiteral literal = (ASTLiteral) node; if (literal.isCharLiteral()) { extras.add("char style"); } if (literal.isIntLiteral()) { extras.add("int style"); } if (literal.isFloatLiteral()) { extras.add("float style"); } if (literal.isStringLiteral()) { extras.add("String style"); } if (literal.isDoubleLiteral()) { extras.add("double style"); } if (literal.isLongLiteral()) { extras.add("long style"); } } else if (node instanceof ASTResultType) { if (((ASTResultType) node).isVoid()) { extras.add("void"); } if (((ASTResultType) node).returnsArray()) { extras.add("returns array"); } } else if (node instanceof ASTSwitchLabel) { if (((ASTSwitchLabel) node).isDefault()) { extras.add("default"); } } else if (node instanceof ASTTryStatement) { if (((ASTTryStatement) node).hasFinally()) { extras.add("has finally"); } } // Output image and extras if (image != null || !extras.isEmpty()) { writer.print(':'); if (image != null) { writer.print(image); } for (String extra : extras) { writer.print('('); writer.print(extra); writer.print(')'); } } writer.println(); } private void collectModifiers(JavaNode node, List<String> extras) { // Standard AccessNode extras if (node instanceof AccessNode) { AccessNode accessNode = (AccessNode) node; if (accessNode.isPackagePrivate()) { extras.add("package private"); } if (accessNode.isPrivate()) { extras.add("private"); } if (accessNode.isPublic()) { extras.add("public"); } if (accessNode.isProtected()) { extras.add("protected"); } if (accessNode.isAbstract()) { extras.add("abstract"); } if (accessNode.isStatic()) { extras.add("static"); } if (accessNode.isFinal()) { extras.add("final"); } if (accessNode.isSynchronized()) { extras.add("synchronized"); } if (accessNode.isNative()) { extras.add("native"); } if (accessNode.isStrictfp()) { extras.add("strict"); } if (accessNode.isTransient()) { extras.add("transient"); } if (accessNode.isDefault()) { extras.add("default"); } } } }