View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.ecmascript.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  import net.sourceforge.pmd.util.StringUtil;
13  
14  public class DumpFacade {
15  
16  	private PrintWriter writer;
17  	private boolean recurse;
18  
19  	public void initializeWith(Writer writer, String prefix, boolean recurse, EcmascriptNode<?> node) {
20  		this.writer = writer instanceof PrintWriter ? (PrintWriter) writer : new PrintWriter(writer);
21  		this.recurse = recurse;
22  		this.dump(node, prefix);
23  		try {
24  			writer.flush();
25  		} catch (IOException e) {
26  			throw new RuntimeException("Problem flushing PrintWriter.", e);
27  		}
28  	}
29  
30  	public Object visit(EcmascriptNode<?> node, Object data) {
31  		dump(node, (String) data);
32  		if (recurse) {
33  			for (int i = 0; i < node.jjtGetNumChildren(); i++) {
34  				visit((EcmascriptNode<?>) node.jjtGetChild(i), data + " ");
35  			}
36  			return data;
37  		} else {
38  			return data;
39  		}
40  	}
41  
42  	private void dump(EcmascriptNode<?> node, String prefix) {
43  		//
44  		// Dump format is generally composed of the following items...
45  		//
46  
47  		// 1) Dump prefix
48  		writer.print(prefix);
49  
50  		// 2) JJT Name of the Node
51  		writer.print(node.toString());
52  
53  		//
54  		// If there are any additional details, then:
55  		// 1) A colon
56  		// 2) The Node.getImage() if it is non-empty
57  		// 3) Extras in parentheses
58  		//
59  
60  		// Standard image handling
61  		String image = node.getImage();
62  
63  		// Special image handling (e.g. Nodes with normally null images)
64  		image = StringUtil.escapeWhitespace(image);
65  
66  		// Extras
67  		List<String> extras = new ArrayList<>();
68  
69  		// Standard DestructuringNode extras
70  		if (node instanceof DestructuringNode) {
71  			if (((DestructuringNode) node).isDestructuring()) {
72  				extras.add("destructuring");
73  			}
74  		}
75  
76  		// Other extras
77  		if (node instanceof ASTArrayComprehension) {
78  			if (((ASTArrayComprehension) node).hasFilter()) {
79  				extras.add("has filter");
80  			}
81  		} else if (node instanceof ASTBreakStatement) {
82  			if (((ASTBreakStatement) node).hasLabel()) {
83  				extras.add("has label");
84  			}
85  		} else if (node instanceof ASTCatchClause) {
86  			if (((ASTCatchClause) node).isIf()) {
87  				extras.add("if");
88  			}
89  		} else if (node instanceof ASTContinueStatement) {
90  			if (((ASTContinueStatement) node).hasLabel()) {
91  				extras.add("has label");
92  			}
93  		} else if (node instanceof ASTExpressionStatement) {
94  			if (((ASTExpressionStatement) node).hasResult()) {
95  				extras.add("has result");
96  			}
97  		} else if (node instanceof ASTForInLoop) {
98  			if (((ASTForInLoop) node).isForEach()) {
99  				extras.add("for each");
100 			}
101 		} else if (node instanceof ASTFunctionCall) {
102 			if (((ASTFunctionCall) node).hasArguments()) {
103 				extras.add("has arguments");
104 			}
105 		} else if (node instanceof ASTFunctionNode) {
106 			if (((ASTFunctionNode) node).isClosure()) {
107 				extras.add("closure");
108 			}
109 			if (((ASTFunctionNode) node).isGetter()) {
110 				extras.add("getter");
111 			}
112 			if (((ASTFunctionNode) node).isSetter()) {
113 				extras.add("setter");
114 			}
115 		} else if (node instanceof ASTIfStatement) {
116 			if (((ASTIfStatement) node).hasElse()) {
117 				extras.add("has else");
118 			}
119 		} else if (node instanceof ASTKeywordLiteral) {
120 			if (((ASTKeywordLiteral) node).isBoolean()) {
121 				extras.add("boolean");
122 			}
123 		} else if (node instanceof ASTLetNode) {
124 			if (((ASTLetNode) node).hasBody()) {
125 				extras.add("has body");
126 			}
127 		} else if (node instanceof ASTName) {
128 			if (((ASTName) node).isLocalName()) {
129 				extras.add("local");
130 			}
131 			if (((ASTName) node).isGlobalName()) {
132 				extras.add("global");
133 			}
134 		} else if (node instanceof ASTNewExpression) {
135 			if (((ASTNewExpression) node).hasArguments()) {
136 				extras.add("has arguments");
137 			}
138 			if (((ASTNewExpression) node).hasInitializer()) {
139 				extras.add("has initializer");
140 			}
141 		} else if (node instanceof ASTNumberLiteral) {
142 			extras.add("Number=" + ((ASTNumberLiteral) node).getNumber());
143 			extras.add("NormalizedImage=" + ((ASTNumberLiteral) node).getNormalizedImage());
144 		} else if (node instanceof ASTObjectProperty) {
145 			if (((ASTObjectProperty) node).isGetter()) {
146 				extras.add("getter");
147 			}
148 			if (((ASTObjectProperty) node).isSetter()) {
149 				extras.add("setter");
150 			}
151 		} else if (node instanceof ASTRegExpLiteral) {
152 			extras.add("Flags=" + ((ASTRegExpLiteral) node).getFlags());
153 		} else if (node instanceof ASTReturnStatement) {
154 			if (((ASTReturnStatement) node).hasResult()) {
155 				extras.add("has result");
156 			}
157 		} else if (node instanceof ASTStringLiteral) {
158 			if (((ASTStringLiteral) node).isSingleQuoted()) {
159 				extras.add("single quoted");
160 			}
161 			if (((ASTStringLiteral) node).isDoubleQuoted()) {
162 				extras.add("double quoted");
163 			}
164 		} else if (node instanceof ASTSwitchCase) {
165 			if (((ASTSwitchCase) node).isDefault()) {
166 				extras.add("default");
167 			}
168 		} else if (node instanceof ASTTryStatement) {
169 			if (((ASTTryStatement) node).hasCatch()) {
170 				extras.add("catch");
171 			}
172 			if (((ASTTryStatement) node).hasFinally()) {
173 				extras.add("finally");
174 			}
175 		} else if (node instanceof ASTUnaryExpression) {
176 			if (((ASTUnaryExpression) node).isPrefix()) {
177 				extras.add("prefix");
178 			}
179 			if (((ASTUnaryExpression) node).isPostfix()) {
180 				extras.add("postfix");
181 			}
182 		}
183 
184 		// Standard EcmascriptNode extras
185 		if (node.hasSideEffects()) {
186 			extras.add("has side effects");
187 		}
188 
189 		// Output image and extras
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 }