1 |
| |
2 |
| package net.sourceforge.pmd.ast; |
3 |
| |
4 |
| import net.sourceforge.pmd.dfa.IDataFlowNode; |
5 |
| import net.sourceforge.pmd.jaxen.Attribute; |
6 |
| import net.sourceforge.pmd.jaxen.DocumentNavigator; |
7 |
| import net.sourceforge.pmd.symboltable.Scope; |
8 |
| import org.apache.xerces.dom.DocumentImpl; |
9 |
| import org.jaxen.BaseXPath; |
10 |
| import org.jaxen.JaxenException; |
11 |
| import org.w3c.dom.Document; |
12 |
| import org.w3c.dom.Element; |
13 |
| |
14 |
| import java.util.ArrayList; |
15 |
| import java.util.Iterator; |
16 |
| import java.util.List; |
17 |
| |
18 |
| public class SimpleNode implements Node { |
19 |
| |
20 |
| protected Node parent; |
21 |
| protected Node[] children; |
22 |
| protected int id; |
23 |
| protected JavaParser parser; |
24 |
| private String image; |
25 |
| private int beginLine = -1; |
26 |
| private int endLine; |
27 |
| private int beginColumn = -1; |
28 |
| private int endColumn; |
29 |
| private Scope scope; |
30 |
| private boolean discardable; |
31 |
| |
32 |
| private IDataFlowNode dataFlowNode; |
33 |
| |
34 |
117
| public IDataFlowNode getDataFlowNode() {
|
35 |
117
| if (this.dataFlowNode == null) {
|
36 |
37
| if (this.parent != null) {
|
37 |
37
| return ((SimpleNode) parent).getDataFlowNode();
|
38 |
| } |
39 |
0
| return null;
|
40 |
| } |
41 |
80
| return dataFlowNode;
|
42 |
| } |
43 |
| |
44 |
18189
| public void discardIfNecessary() {
|
45 |
18189
| if (discardable) {
|
46 |
17921
| SimpleNode parent = (SimpleNode) this.jjtGetParent();
|
47 |
17921
| SimpleNode kid = (SimpleNode) this.jjtGetChild(0);
|
48 |
17921
| kid.jjtSetParent(parent);
|
49 |
17921
| parent.jjtReplaceChild(this, kid);
|
50 |
| } |
51 |
| } |
52 |
| |
53 |
211
| public void setDataFlowNode(IDataFlowNode dataFlowNode) {
|
54 |
211
| this.dataFlowNode = dataFlowNode;
|
55 |
| } |
56 |
| |
57 |
20458
| public void setDiscardable() {
|
58 |
20458
| this.discardable = true;
|
59 |
| } |
60 |
| |
61 |
259
| public void setUnDiscardable() {
|
62 |
259
| this.discardable = false;
|
63 |
| } |
64 |
| |
65 |
69895
| public SimpleNode(int i) {
|
66 |
69895
| id = i;
|
67 |
| } |
68 |
| |
69 |
46092
| public SimpleNode(JavaParser p, int i) {
|
70 |
46092
| this(i);
|
71 |
46092
| parser = p;
|
72 |
| } |
73 |
| |
74 |
46092
| public void jjtOpen() {
|
75 |
46092
| if (beginLine == -1 && parser.token.next != null) {
|
76 |
37428
| beginLine = parser.token.next.beginLine;
|
77 |
37428
| beginColumn = parser.token.next.beginColumn;
|
78 |
| } |
79 |
| } |
80 |
| |
81 |
46035
| public void jjtClose() {
|
82 |
46035
| if (beginLine == -1 && (children == null || children.length == 0)) {
|
83 |
589
| beginColumn = parser.token.beginColumn;
|
84 |
| } |
85 |
46035
| if (beginLine == -1) {
|
86 |
8628
| beginLine = parser.token.beginLine;
|
87 |
| } |
88 |
46035
| endLine = parser.token.endLine;
|
89 |
46035
| endColumn = parser.token.endColumn;
|
90 |
| } |
91 |
| |
92 |
27491
| public void setScope(Scope scope) {
|
93 |
27491
| this.scope = scope;
|
94 |
| } |
95 |
| |
96 |
28410
| public Scope getScope() {
|
97 |
28410
| if (scope == null) {
|
98 |
17203
| return ((SimpleNode) parent).getScope();
|
99 |
| } |
100 |
11207
| return scope;
|
101 |
| } |
102 |
| |
103 |
6782
| public int getBeginLine() {
|
104 |
6782
| return beginLine;
|
105 |
| } |
106 |
| |
107 |
24638
| public void testingOnly__setBeginLine(int i) {
|
108 |
24638
| this.beginLine = i;
|
109 |
| } |
110 |
| |
111 |
44436
| public void testingOnly__setBeginColumn(int i) {
|
112 |
44436
| this.beginColumn = i;
|
113 |
| } |
114 |
| |
115 |
3270
| public int getBeginColumn() {
|
116 |
3270
| if (beginColumn != -1) {
|
117 |
3223
| return beginColumn;
|
118 |
| } else { |
119 |
47
| if ((children != null) && (children.length > 0)) {
|
120 |
47
| return ((SimpleNode) children[0]).getBeginColumn();
|
121 |
| } else { |
122 |
0
| throw new RuntimeException("Unable to determine begining line of Node.");
|
123 |
| } |
124 |
| } |
125 |
| } |
126 |
| |
127 |
27645
| public String getImage() {
|
128 |
27645
| return image;
|
129 |
| } |
130 |
| |
131 |
5829
| public void setImage(String image) {
|
132 |
5829
| this.image = image;
|
133 |
| } |
134 |
| |
135 |
53
| public int getEndLine() {
|
136 |
53
| return endLine;
|
137 |
| } |
138 |
| |
139 |
3223
| public int getEndColumn() {
|
140 |
3223
| return endColumn;
|
141 |
| } |
142 |
| |
143 |
| |
144 |
| |
145 |
| |
146 |
| |
147 |
| |
148 |
| |
149 |
6682
| public Node getFirstParentOfType(Class parentType) {
|
150 |
6682
| Node parentNode = jjtGetParent();
|
151 |
6682
| while (parentNode != null && parentNode.getClass() != parentType) {
|
152 |
5346
| parentNode = parentNode.jjtGetParent();
|
153 |
| } |
154 |
6682
| return parentNode;
|
155 |
| } |
156 |
| |
157 |
| |
158 |
| |
159 |
| |
160 |
| |
161 |
| |
162 |
| |
163 |
3
| public List getParentsOfType(Class parentType) {
|
164 |
3
| List parents = new ArrayList();
|
165 |
3
| Node parentNode = jjtGetParent();
|
166 |
3
| while (parentNode != null) {
|
167 |
33
| if (parentNode.getClass() == parentType) {
|
168 |
0
| parents.add(parentNode);
|
169 |
| } |
170 |
33
| parentNode = parentNode.jjtGetParent();
|
171 |
| } |
172 |
3
| return parents;
|
173 |
| } |
174 |
| |
175 |
16666
| public List findChildrenOfType(Class targetType) {
|
176 |
16666
| List list = new ArrayList();
|
177 |
16666
| findChildrenOfType(targetType, list);
|
178 |
16666
| return list;
|
179 |
| } |
180 |
| |
181 |
16689
| public void findChildrenOfType(Class targetType, List results) {
|
182 |
16689
| findChildrenOfType(this, targetType, results, true);
|
183 |
| } |
184 |
| |
185 |
27
| public void findChildrenOfType(Class targetType, List results, boolean descendIntoNestedClasses) {
|
186 |
27
| this.findChildrenOfType(this, targetType, results, descendIntoNestedClasses);
|
187 |
| } |
188 |
| |
189 |
515159
| private void findChildrenOfType(Node node, Class targetType, List results, boolean descendIntoNestedClasses) {
|
190 |
515159
| if (node.getClass().equals(targetType)) {
|
191 |
18461
| results.add(node);
|
192 |
| } |
193 |
| |
194 |
515159
| if (!descendIntoNestedClasses) {
|
195 |
258
| if (node instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node).isNested()) {
|
196 |
0
| return;
|
197 |
| } |
198 |
| |
199 |
258
| if (node instanceof ASTClassOrInterfaceBodyDeclaration && ((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
|
200 |
3
| return;
|
201 |
| } |
202 |
| } |
203 |
| |
204 |
515156
| for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
205 |
642664
| Node child = node.jjtGetChild(i);
|
206 |
642664
| if (child.jjtGetNumChildren() > 0) {
|
207 |
498443
| findChildrenOfType(child, targetType, results, descendIntoNestedClasses);
|
208 |
| } else { |
209 |
144221
| if (child.getClass().equals(targetType)) {
|
210 |
2156
| results.add(child);
|
211 |
| } |
212 |
| } |
213 |
| } |
214 |
| } |
215 |
| |
216 |
63031
| public void jjtSetParent(Node n) {
|
217 |
63031
| parent = n;
|
218 |
| } |
219 |
| |
220 |
85617
| public Node jjtGetParent() {
|
221 |
85617
| return parent;
|
222 |
| } |
223 |
| |
224 |
17922
| public void jjtReplaceChild(Node old, Node newNode) {
|
225 |
18320
| for (int i = 0; i < children.length; i++) {
|
226 |
18320
| if (children[i] == old) {
|
227 |
17922
| children[i] = newNode;
|
228 |
17922
| return;
|
229 |
| } |
230 |
| } |
231 |
0
| throw new RuntimeException("PMD INTERNAL ERROR: SimpleNode.jjtReplaceChild called to replace a node, but couldn't find the old node");
|
232 |
| } |
233 |
| |
234 |
45131
| public void jjtAddChild(Node n, int i) {
|
235 |
45131
| if (children == null) {
|
236 |
37986
| children = new Node[i + 1];
|
237 |
7145
| } else if (i >= children.length) {
|
238 |
7
| Node c[] = new Node[i + 1];
|
239 |
7
| System.arraycopy(children, 0, c, 0, children.length);
|
240 |
7
| children = c;
|
241 |
| } |
242 |
45131
| children[i] = n;
|
243 |
| } |
244 |
| |
245 |
723530
| public Node jjtGetChild(int i) {
|
246 |
723530
| return children[i];
|
247 |
| } |
248 |
| |
249 |
1889102
| public int jjtGetNumChildren() {
|
250 |
1889102
| return (children == null) ? 0 : children.length;
|
251 |
| } |
252 |
| |
253 |
| |
254 |
| |
255 |
| |
256 |
0
| public Object jjtAccept(JavaParserVisitor visitor, Object data) {
|
257 |
0
| return visitor.visit(this, data);
|
258 |
| } |
259 |
| |
260 |
| |
261 |
| |
262 |
| |
263 |
64389
| public Object childrenAccept(JavaParserVisitor visitor, Object data) {
|
264 |
64389
| if (children != null) {
|
265 |
49942
| for (int i = 0; i < children.length; ++i) {
|
266 |
62511
| children[i].jjtAccept(visitor, data);
|
267 |
| } |
268 |
| } |
269 |
64389
| return data;
|
270 |
| } |
271 |
| |
272 |
| |
273 |
| |
274 |
| |
275 |
| |
276 |
| |
277 |
| |
278 |
12755
| public String toString() {
|
279 |
12755
| return JavaParserTreeConstants.jjtNodeName[id];
|
280 |
| } |
281 |
| |
282 |
0
| public String toString(String prefix) {
|
283 |
0
| return prefix + toString();
|
284 |
| } |
285 |
| |
286 |
0
| public Document asXml() {
|
287 |
0
| Document document = new DocumentImpl();
|
288 |
0
| appendElement(document);
|
289 |
0
| return document;
|
290 |
| } |
291 |
| |
292 |
0
| protected void appendElement(org.w3c.dom.Node parentNode) {
|
293 |
0
| DocumentNavigator docNav = new DocumentNavigator();
|
294 |
0
| Document ownerDocument = parentNode.getOwnerDocument();
|
295 |
0
| if( ownerDocument == null )
|
296 |
| { |
297 |
| |
298 |
0
| ownerDocument = (Document) parentNode;
|
299 |
| } |
300 |
0
| String elementName = docNav.getElementName(this);
|
301 |
0
| Element element = ownerDocument.createElement(elementName);
|
302 |
0
| parentNode.appendChild( element );
|
303 |
0
| for (Iterator iter = docNav.getAttributeAxisIterator(this); iter.hasNext();) {
|
304 |
0
| Attribute attr = (Attribute) iter.next();
|
305 |
0
| element.setAttribute(attr.getName(), attr.getValue());
|
306 |
| } |
307 |
0
| for (Iterator iter = docNav.getChildAxisIterator(this); iter.hasNext();) {
|
308 |
0
| SimpleNode child = (SimpleNode) iter.next();
|
309 |
0
| child.appendElement(element);
|
310 |
| } |
311 |
| } |
312 |
| |
313 |
| |
314 |
| |
315 |
0
| public void dump(String prefix) {
|
316 |
0
| System.out.println(toString(prefix) + (image == null ? "" : ":" + image));
|
317 |
0
| dumpChildren(prefix);
|
318 |
| } |
319 |
| |
320 |
0
| protected void dumpChildren(String prefix) {
|
321 |
0
| if (children != null) {
|
322 |
0
| for (int i = 0; i < children.length; ++i) {
|
323 |
0
| SimpleNode n = (SimpleNode) children[i];
|
324 |
0
| if (n != null) {
|
325 |
0
| n.dump(prefix + " ");
|
326 |
| } |
327 |
| } |
328 |
| } |
329 |
| } |
330 |
| |
331 |
| |
332 |
| |
333 |
| |
334 |
| |
335 |
| |
336 |
| |
337 |
| |
338 |
899
| public Node getFirstChildOfType(Class childType) {
|
339 |
899
| return getFirstChildOfType(childType, this);
|
340 |
| } |
341 |
| |
342 |
2292
| private Node getFirstChildOfType(Class childType, Node node) {
|
343 |
2292
| for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
344 |
2279
| Node n = node.jjtGetChild(i);
|
345 |
2279
| if (n != null) {
|
346 |
2277
| if (n.getClass().equals(childType))
|
347 |
884
| return n;
|
348 |
1393
| Node n2 = getFirstChildOfType(childType, n);
|
349 |
1393
| if (n2 != null)
|
350 |
141
| return n2;
|
351 |
| } |
352 |
| } |
353 |
1267
| return null;
|
354 |
| } |
355 |
| |
356 |
| |
357 |
| |
358 |
| |
359 |
| |
360 |
| |
361 |
| |
362 |
| |
363 |
14
| public final boolean containsChildOfType(Class type) {
|
364 |
14
| return !findChildrenOfType(type).isEmpty();
|
365 |
| } |
366 |
| |
367 |
4
| public List findChildNodesWithXPath(String xpathString) throws JaxenException {
|
368 |
4
| return new BaseXPath(xpathString, new DocumentNavigator()).selectNodes(this);
|
369 |
| } |
370 |
| } |
371 |
| |