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