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 }