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) ? (PrintWriter) writer : 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, (String) data);
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(((ASTBooleanLiteral) node).isTrue());
059 } else if (node instanceof ASTPrimaryPrefix) {
060 ASTPrimaryPrefix primaryPrefix = (ASTPrimaryPrefix) node;
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 = (ASTPrimarySuffix) node;
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 = (AccessNode) node;
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 = (Dimensionable) node;
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(((ASTArguments) node).getArgumentCount()));
137 } else if (node instanceof ASTAssignmentOperator) {
138 extras.add(((ASTAssignmentOperator) node).isCompound() ? "compound" : "simple");
139 } else if (node instanceof ASTClassOrInterfaceBodyDeclaration) {
140 if (((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
141 extras.add("anonymous inner class");
142 }
143 if (((ASTClassOrInterfaceBodyDeclaration) node).isEnumChild()) {
144 extras.add("enum child");
145 }
146 } else if (node instanceof ASTBlock) {
147 if (((ASTBlock) node).containsComment()) {
148 extras.add("contains comment");
149 }
150 } else if (node instanceof ASTClassOrInterfaceDeclaration) {
151 extras.add(((ASTClassOrInterfaceDeclaration) node).isInterface() ? "interface" : "class");
152 if (((ASTClassOrInterfaceDeclaration) node).isNested()) {
153 extras.add("nested");
154 }
155 } else if (node instanceof ASTConditionalExpression) {
156 if (((ASTConditionalExpression) node).isTernary()) {
157 extras.add("ternary");
158 }
159 } else if (node instanceof ASTConstructorDeclaration) {
160 extras.add(String.valueOf(((ASTConstructorDeclaration) node).getParameterCount()));
161 if (((ASTConstructorDeclaration) node).containsComment()) {
162 extras.add("contains comment");
163 }
164 } else if (node instanceof ASTExplicitConstructorInvocation) {
165 extras.add(String.valueOf(((ASTExplicitConstructorInvocation) node).getArgumentCount()));
166 if (((ASTExplicitConstructorInvocation) node).isThis()) {
167 extras.add("this");
168 }
169 if (((ASTExplicitConstructorInvocation) node).isSuper()) {
170 extras.add("super");
171 }
172 } else if (node instanceof ASTFormalParameter) {
173 if (((ASTFormalParameter) node).isVarargs()) {
174 extras.add("varargs");
175 }
176 } else if (node instanceof ASTFormalParameters) {
177 extras.add(String.valueOf(((ASTFormalParameters) node).getParameterCount()));
178 } else if (node instanceof ASTIfStatement) {
179 if (((ASTIfStatement) node).hasElse()) {
180 extras.add("has else");
181 }
182 } else if (node instanceof ASTImportDeclaration) {
183 if (((ASTImportDeclaration) node).isImportOnDemand()) {
184 extras.add("on demand");
185 }
186 if (((ASTImportDeclaration) node).isStatic()) {
187 extras.add("static");
188 }
189 } else if (node instanceof ASTInitializer) {
190 extras.add(((ASTInitializer) node).isStatic() ? "static" : "nonstatic");
191 } else if (node instanceof ASTLiteral) {
192 if (((ASTLiteral) node).isCharLiteral()) {
193 extras.add("char style");
194 }
195 if (((ASTLiteral) node).isIntLiteral()) {
196 extras.add("int style");
197 }
198 if (((ASTLiteral) node).isFloatLiteral()) {
199 extras.add("float style");
200 }
201 if (((ASTLiteral) node).isStringLiteral()) {
202 extras.add("String style");
203 }
204 } else if (node instanceof ASTResultType) {
205 if (((ASTResultType) node).isVoid()) {
206 extras.add("void");
207 }
208 if (((ASTResultType) node).returnsArray()) {
209 extras.add("returns array");
210 }
211 } else if (node instanceof ASTSwitchLabel) {
212 if (((ASTSwitchLabel) node).isDefault()) {
213 extras.add("default");
214 }
215 } else if (node instanceof ASTTryStatement) {
216 if (((ASTTryStatement) node).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 }
|