DumpFacade.java
001 package net.sourceforge.pmd.lang.java.ast;
002 
003 import java.io.IOException;
004 import java.io.PrintWriter;
005 import java.io.Writer;
006 import java.util.ArrayList;
007 import java.util.List;
008 
009 public class DumpFacade extends JavaParserVisitorAdapter {
010 
011     private PrintWriter writer;
012     private boolean recurse;
013 
014     public void initializeWith(Writer writer, String prefix, boolean recurse, JavaNode node) {
015   this.writer = (writer instanceof PrintWriter(PrintWriterwriter : new PrintWriter(writer);
016   this.recurse = recurse;
017   this.visit(node, prefix);
018   try {
019       writer.flush();
020   catch (IOException e) {
021       throw new RuntimeException("Problem flushing PrintWriter.", e);
022   }
023     }
024 
025     @Override
026     public Object visit(JavaNode node, Object data) {
027   dump(node, (Stringdata);
028   if (recurse) {
029       return super.visit(node, data + " ");
030   else {
031       return data;
032   }
033     }
034 
035     private void dump(JavaNode node, String prefix) {
036   //
037   // Dump format is generally composed of the following items...
038   //
039 
040   // 1) Dump prefix
041   writer.print(prefix);
042 
043   // 2) JJT Name of the Node
044   writer.print(node.toString());
045 
046   //
047   // If there are any additional details, then:
048   // 1) A colon
049   // 2) The Node.getImage() if it is non-empty
050   // 3) Extras in parentheses
051   //
052 
053   // Standard image handling
054   String image = node.getImage();
055 
056   // Special image handling (e.g. Nodes with normally null images)
057   if (node instanceof ASTBooleanLiteral) {
058       image = String.valueOf(((ASTBooleanLiteralnode).isTrue());
059   else if (node instanceof ASTPrimaryPrefix) {
060       ASTPrimaryPrefix primaryPrefix = (ASTPrimaryPrefixnode;
061       if (primaryPrefix.usesSuperModifier()) {
062     image = "super." + image;
063       else if (primaryPrefix.usesThisModifier()) {
064     if (image == null) {
065         image = "this";
066     else {
067         image = "this." + image;
068     }
069       }
070   else if (node instanceof ASTPrimarySuffix) {
071       ASTPrimarySuffix primarySuffix = (ASTPrimarySuffixnode;
072       if (primarySuffix.isArrayDereference()) {
073     if (image == null) {
074         image = "[";
075     else {
076         image = "[" + image;
077     }
078       }
079   }
080 
081   // Extras
082   List<String> extras = new ArrayList<String>();
083 
084   // Standard AccessNode extras
085   if (node instanceof AccessNode) {
086       AccessNode accessNode = (AccessNodenode;
087       if (accessNode.isPackagePrivate()) {
088     extras.add("package private");
089       }
090       if (accessNode.isPrivate()) {
091     extras.add("private");
092       }
093       if (accessNode.isPublic()) {
094     extras.add("public");
095       }
096       if (accessNode.isProtected()) {
097     extras.add("protected");
098       }
099       if (accessNode.isAbstract()) {
100     extras.add("abstract");
101       }
102       if (accessNode.isStatic()) {
103     extras.add("static");
104       }
105       if (accessNode.isFinal()) {
106     extras.add("final");
107       }
108       if (accessNode.isSynchronized()) {
109     extras.add("synchronized");
110       }
111       if (accessNode.isNative()) {
112     extras.add("native");
113       }
114       if (accessNode.isStrictfp()) {
115     extras.add("strict");
116       }
117       if (accessNode.isTransient()) {
118     extras.add("transient");
119       }
120   }
121 
122   // Standard Dimensionable extras
123   if (node instanceof Dimensionable) {
124       Dimensionable dimensionable = (Dimensionablenode;
125       if (dimensionable.isArray()) {
126     StringBuilder extra = new StringBuilder("array");
127     for (int i = 0; i < dimensionable.getArrayDepth(); i++) {
128         extra.append("[");
129     }
130     extras.add(extra.toString());
131       }
132   }
133 
134   // Other extras
135   if (node instanceof ASTArguments) {
136       extras.add(String.valueOf(((ASTArgumentsnode).getArgumentCount()));
137   else if (node instanceof ASTAssignmentOperator) {
138       extras.add(((ASTAssignmentOperatornode).isCompound() "compound" "simple");
139   else if (node instanceof ASTClassOrInterfaceBodyDeclaration) {
140       if (((ASTClassOrInterfaceBodyDeclarationnode).isAnonymousInnerClass()) {
141     extras.add("anonymous inner class");
142       }
143       if (((ASTClassOrInterfaceBodyDeclarationnode).isEnumChild()) {
144     extras.add("enum child");
145       }
146   else if (node instanceof ASTBlock) {
147       if (((ASTBlocknode).containsComment()) {
148     extras.add("contains comment");
149       }
150   else if (node instanceof ASTClassOrInterfaceDeclaration) {
151       extras.add(((ASTClassOrInterfaceDeclarationnode).isInterface() "interface" "class");
152       if (((ASTClassOrInterfaceDeclarationnode).isNested()) {
153     extras.add("nested");
154       }
155   else if (node instanceof ASTConditionalExpression) {
156       if (((ASTConditionalExpressionnode).isTernary()) {
157     extras.add("ternary");
158       }
159   else if (node instanceof ASTConstructorDeclaration) {
160       extras.add(String.valueOf(((ASTConstructorDeclarationnode).getParameterCount()));
161       if (((ASTConstructorDeclarationnode).containsComment()) {
162     extras.add("contains comment");
163       }
164   else if (node instanceof ASTExplicitConstructorInvocation) {
165       extras.add(String.valueOf(((ASTExplicitConstructorInvocationnode).getArgumentCount()));
166       if (((ASTExplicitConstructorInvocationnode).isThis()) {
167     extras.add("this");
168       }
169       if (((ASTExplicitConstructorInvocationnode).isSuper()) {
170     extras.add("super");
171       }
172   else if (node instanceof ASTFormalParameter) {
173       if (((ASTFormalParameternode).isVarargs()) {
174     extras.add("varargs");
175       }
176   else if (node instanceof ASTFormalParameters) {
177       extras.add(String.valueOf(((ASTFormalParametersnode).getParameterCount()));
178   else if (node instanceof ASTIfStatement) {
179       if (((ASTIfStatementnode).hasElse()) {
180     extras.add("has else");
181       }
182   else if (node instanceof ASTImportDeclaration) {
183       if (((ASTImportDeclarationnode).isImportOnDemand()) {
184     extras.add("on demand");
185       }
186       if (((ASTImportDeclarationnode).isStatic()) {
187     extras.add("static");
188       }
189   else if (node instanceof ASTInitializer) {
190       extras.add(((ASTInitializernode).isStatic() "static" "nonstatic");
191   else if (node instanceof ASTLiteral) {
192       if (((ASTLiteralnode).isCharLiteral()) {
193     extras.add("char style");
194       }
195       if (((ASTLiteralnode).isIntLiteral()) {
196     extras.add("int style");
197       }
198       if (((ASTLiteralnode).isFloatLiteral()) {
199     extras.add("float style");
200       }
201       if (((ASTLiteralnode).isStringLiteral()) {
202     extras.add("String style");
203       }
204   else if (node instanceof ASTResultType) {
205       if (((ASTResultTypenode).isVoid()) {
206     extras.add("void");
207       }
208       if (((ASTResultTypenode).returnsArray()) {
209     extras.add("returns array");
210       }
211   else if (node instanceof ASTSwitchLabel) {
212       if (((ASTSwitchLabelnode).isDefault()) {
213     extras.add("default");
214       }
215   else if (node instanceof ASTTryStatement) {
216       if (((ASTTryStatementnode).hasFinally()) {
217     extras.add("has finally");
218       }
219   }
220 
221   // Output image and extras
222   if (image != null || !extras.isEmpty()) {
223       writer.print(":");
224       if (image != null) {
225     writer.print(image);
226       }
227       for (String extra : extras) {
228     writer.print("(");
229     writer.print(extra);
230     writer.print(")");
231       }
232   }
233 
234   writer.println();
235     }
236 }