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 if (((ASTLiteral) node).isCharLiteral()) {
161 extras.add("char style");
162 }
163 if (((ASTLiteral) node).isIntLiteral()) {
164 extras.add("int style");
165 }
166 if (((ASTLiteral) node).isFloatLiteral()) {
167 extras.add("float style");
168 }
169 if (((ASTLiteral) node).isStringLiteral()) {
170 extras.add("String style");
171 }
172 } else if (node instanceof ASTResultType) {
173 if (((ASTResultType) node).isVoid()) {
174 extras.add("void");
175 }
176 if (((ASTResultType) node).returnsArray()) {
177 extras.add("returns array");
178 }
179 } else if (node instanceof ASTSwitchLabel) {
180 if (((ASTSwitchLabel) node).isDefault()) {
181 extras.add("default");
182 }
183 } else if (node instanceof ASTTryStatement) {
184 if (((ASTTryStatement) node).hasFinally()) {
185 extras.add("has finally");
186 }
187 }
188
189
190 if (image != null || !extras.isEmpty()) {
191 writer.print(':');
192 if (image != null) {
193 writer.print(image);
194 }
195 for (String extra : extras) {
196 writer.print('(');
197 writer.print(extra);
198 writer.print(')');
199 }
200 }
201
202 writer.println();
203 }
204
205 private void collectModifiers(JavaNode node, List<String> extras) {
206
207 if (node instanceof AccessNode) {
208 AccessNode accessNode = (AccessNode) node;
209 if (accessNode.isPackagePrivate()) {
210 extras.add("package private");
211 }
212 if (accessNode.isPrivate()) {
213 extras.add("private");
214 }
215 if (accessNode.isPublic()) {
216 extras.add("public");
217 }
218 if (accessNode.isProtected()) {
219 extras.add("protected");
220 }
221 if (accessNode.isAbstract()) {
222 extras.add("abstract");
223 }
224 if (accessNode.isStatic()) {
225 extras.add("static");
226 }
227 if (accessNode.isFinal()) {
228 extras.add("final");
229 }
230 if (accessNode.isSynchronized()) {
231 extras.add("synchronized");
232 }
233 if (accessNode.isNative()) {
234 extras.add("native");
235 }
236 if (accessNode.isStrictfp()) {
237 extras.add("strict");
238 }
239 if (accessNode.isTransient()) {
240 extras.add("transient");
241 }
242 if (accessNode.isDefault()) {
243 extras.add("default");
244 }
245 }
246 }
247 }