View Javadoc

    1   package net.sourceforge.pmd.lang.java.ast;
    2
    3   import java.io.IOException;
    4   import java.io.PrintWriter;
    5   import java.io.Writer;
    6   import java.util.ArrayList;
    7   import java.util.List;
    8
    9   public class DumpFacade extends JavaParserVisitorAdapter {
    10
    11  	private PrintWriter writer;
    12  	private boolean recurse;
    13
    14  	public void initializeWith(Writer writer, String prefix, boolean recurse, JavaNode node) {
    15  		this.writer = (writer instanceof PrintWriter) ? (PrintWriter) writer : new PrintWriter(writer);
    16  		this.recurse = recurse;
    17  		this.visit(node, prefix);
    18  		try {
    19  			writer.flush();
    20  		} catch (IOException e) {
    21  			throw new RuntimeException("Problem flushing PrintWriter.", e);
    22  		}
    23  	}
    24
    25  	@Override
    26  	public Object visit(JavaNode node, Object data) {
    27  		dump(node, (String) data);
    28  		if (recurse) {
    29  			return super.visit(node, data + " ");
    30  		} else {
    31  			return data;
    32  		}
    33  	}
    34
    35  	private void dump(JavaNode node, String prefix) {
    36  		//
    37  		// Dump format is generally composed of the following items...
    38  		//
    39
    40  		// 1) Dump prefix
    41  		writer.print(prefix);
    42
    43  		// 2) JJT Name of the Node
    44  		writer.print(node.toString());
    45
    46  		//
    47  		// If there are any additional details, then:
    48  		// 1) A colon
    49  		// 2) The Node.getImage() if it is non-empty
    50  		// 3) Extras in parentheses
    51  		//
    52
    53  		// Standard image handling
    54  		String image = node.getImage();
    55
    56  		// Special image handling (e.g. Nodes with normally null images)
    57  		if (node instanceof ASTBooleanLiteral) {
    58  			image = String.valueOf(((ASTBooleanLiteral) node).isTrue());
    59  		} else if (node instanceof ASTPrimaryPrefix) {
    60  			ASTPrimaryPrefix primaryPrefix = (ASTPrimaryPrefix) node;
    61  			String result = null;
    62  			if (primaryPrefix.usesSuperModifier()) {
    63  				result = "super";
    64  			} else if (primaryPrefix.usesThisModifier()) {
    65  				result = "this";
    66  			}
    67  			if (image != null) {
    68  				result += "." + image;
    69  			}
    70  			image = result;
    71  		} else if (node instanceof ASTPrimarySuffix) {
    72  			ASTPrimarySuffix primarySuffix = (ASTPrimarySuffix) node;
    73  			if (primarySuffix.isArrayDereference()) {
    74  				if (image == null) {
    75  					image = "[";
    76  				} else {
    77  					image = "[" + image;
    78  				}
    79  			}
    80  		}
    81
    82  		// Extras
    83  		List<String> extras = new ArrayList<String>();
    84
    85  		collectModifiers(node, extras);
    86
    87  		// Standard Dimensionable extras
    88  		if (node instanceof Dimensionable) {
    89  			Dimensionable dimensionable = (Dimensionable) node;
    90  			if (dimensionable.isArray()) {
    91  				StringBuilder extra = new StringBuilder("array");
    92  				for (int i = 0; i < dimensionable.getArrayDepth(); i++) {
    93  					extra.append('[');
    94  				}
    95  				extras.add(extra.toString());
    96  			}
    97  		}
    98
    99  		// Other extras
    100 		if (node instanceof ASTArguments) {
    101 			extras.add(String.valueOf(((ASTArguments) node).getArgumentCount()));
    102 		} else if (node instanceof ASTAssignmentOperator) {
    103 			extras.add(((ASTAssignmentOperator) node).isCompound() ? "compound" : "simple");
    104 		} else if (node instanceof ASTClassOrInterfaceBodyDeclaration) {
    105 			if (((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
    106 				extras.add("anonymous inner class");
    107 			}
    108 			if (((ASTClassOrInterfaceBodyDeclaration) node).isEnumChild()) {
    109 				extras.add("enum child");
    110 			}
    111 		} else if (node instanceof ASTBlock) {
    112 			if (((ASTBlock) node).containsComment()) {
    113 				extras.add("contains comment");
    114 			}
    115 		} else if (node instanceof ASTClassOrInterfaceDeclaration) {
    116 			extras.add(((ASTClassOrInterfaceDeclaration) node).isInterface() ? "interface" : "class");
    117 			if (((ASTClassOrInterfaceDeclaration) node).isNested()) {
    118 				extras.add("nested");
    119 			}
    120 		} else if (node instanceof ASTConditionalExpression) {
    121 			if (((ASTConditionalExpression) node).isTernary()) {
    122 				extras.add("ternary");
    123 			}
    124 		} else if (node instanceof ASTConstructorDeclaration) {
    125 			extras.add(String.valueOf(((ASTConstructorDeclaration) node).getParameterCount()));
    126 			if (((ASTConstructorDeclaration) node).containsComment()) {
    127 				extras.add("contains comment");
    128 			}
    129 		} else if (node instanceof ASTExplicitConstructorInvocation) {
    130 			extras.add(String.valueOf(((ASTExplicitConstructorInvocation) node).getArgumentCount()));
    131 			if (((ASTExplicitConstructorInvocation) node).isThis()) {
    132 				extras.add("this");
    133 			}
    134 			if (((ASTExplicitConstructorInvocation) node).isSuper()) {
    135 				extras.add("super");
    136 			}
    137 		} else if (node instanceof ASTFormalParameter) {
    138 			if (((ASTFormalParameter) node).isVarargs()) {
    139 				extras.add("varargs");
    140 			}
    141 		} else if (node instanceof ASTFormalParameters) {
    142 			extras.add(String.valueOf(((ASTFormalParameters) node).getParameterCount()));
    143 		} else if (node instanceof ASTIfStatement) {
    144 			if (((ASTIfStatement) node).hasElse()) {
    145 				extras.add("has else");
    146 			}
    147 		} else if (node instanceof ASTImportDeclaration) {
    148 			if (((ASTImportDeclaration) node).isImportOnDemand()) {
    149 				extras.add("on demand");
    150 			}
    151 			if (((ASTImportDeclaration) node).isStatic()) {
    152 				extras.add("static");
    153 			}
    154 		} else if (node instanceof ASTInitializer) {
    155 			extras.add(((ASTInitializer) node).isStatic() ? "static" : "nonstatic");
    156 		} else if (node instanceof ASTLiteral) {
    157 			if (((ASTLiteral) node).isCharLiteral()) {
    158 				extras.add("char style");
    159 			}
    160 			if (((ASTLiteral) node).isIntLiteral()) {
    161 				extras.add("int style");
    162 			}
    163 			if (((ASTLiteral) node).isFloatLiteral()) {
    164 				extras.add("float style");
    165 			}
    166 			if (((ASTLiteral) node).isStringLiteral()) {
    167 				extras.add("String style");
    168 			}
    169 		} else if (node instanceof ASTResultType) {
    170 			if (((ASTResultType) node).isVoid()) {
    171 				extras.add("void");
    172 			}
    173 			if (((ASTResultType) node).returnsArray()) {
    174 				extras.add("returns array");
    175 			}
    176 		} else if (node instanceof ASTSwitchLabel) {
    177 			if (((ASTSwitchLabel) node).isDefault()) {
    178 				extras.add("default");
    179 			}
    180 		} else if (node instanceof ASTTryStatement) {
    181 			if (((ASTTryStatement) node).hasFinally()) {
    182 				extras.add("has finally");
    183 			}
    184 		}
    185
    186 		// Output image and extras
    187 		if (image != null || !extras.isEmpty()) {
    188 			writer.print(':');
    189 			if (image != null) {
    190 				writer.print(image);
    191 			}
    192 			for (String extra : extras) {
    193 				writer.print('(');
    194 				writer.print(extra);
    195 				writer.print(')');
    196 			}
    197 		}
    198
    199 		writer.println();
    200 	}
    201
    202 	private void collectModifiers(JavaNode node, List<String> extras) {
    203 		// Standard AccessNode extras
    204 		if (node instanceof AccessNode) {
    205 			AccessNode accessNode = (AccessNode) node;
    206 			if (accessNode.isPackagePrivate()) {
    207 				extras.add("package private");
    208 			}
    209 			if (accessNode.isPrivate()) {
    210 				extras.add("private");
    211 			}
    212 			if (accessNode.isPublic()) {
    213 				extras.add("public");
    214 			}
    215 			if (accessNode.isProtected()) {
    216 				extras.add("protected");
    217 			}
    218 			if (accessNode.isAbstract()) {
    219 				extras.add("abstract");
    220 			}
    221 			if (accessNode.isStatic()) {
    222 				extras.add("static");
    223 			}
    224 			if (accessNode.isFinal()) {
    225 				extras.add("final");
    226 			}
    227 			if (accessNode.isSynchronized()) {
    228 				extras.add("synchronized");
    229 			}
    230 			if (accessNode.isNative()) {
    231 				extras.add("native");
    232 			}
    233 			if (accessNode.isStrictfp()) {
    234 				extras.add("strict");
    235 			}
    236 			if (accessNode.isTransient()) {
    237 				extras.add("transient");
    238 			}
    239 		}
    240 	}
    241 }