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 abstract 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 |
| protected int beginLine = -1; |
26 |
| protected int endLine; |
27 |
| protected int beginColumn = -1; |
28 |
| protected int endColumn; |
29 |
| private Scope scope; |
30 |
| private boolean discardable; |
31 |
| private IDataFlowNode dataFlowNode; |
32 |
| |
33 |
117
| public IDataFlowNode getDataFlowNode() {
|
34 |
117
| if (this.dataFlowNode == null) {
|
35 |
37
| if (this.parent != null) {
|
36 |
37
| return ((SimpleNode) parent).getDataFlowNode();
|
37 |
| } |
38 |
0
| return null;
|
39 |
| } |
40 |
80
| return dataFlowNode;
|
41 |
| } |
42 |
| |
43 |
0
| public void discardIfNecessary() {
|
44 |
0
| if (discardable) {
|
45 |
0
| SimpleNode parent = (SimpleNode) this.jjtGetParent();
|
46 |
0
| SimpleNode kid = (SimpleNode) this.jjtGetChild(0);
|
47 |
0
| kid.jjtSetParent(parent);
|
48 |
0
| parent.jjtReplaceChild(this, kid);
|
49 |
| } |
50 |
| } |
51 |
| |
52 |
211
| public void setDataFlowNode(IDataFlowNode dataFlowNode) {
|
53 |
211
| this.dataFlowNode = dataFlowNode;
|
54 |
| } |
55 |
| |
56 |
6898
| public void setDiscardable() {
|
57 |
6898
| this.discardable = true;
|
58 |
| } |
59 |
| |
60 |
0
| public void setUnDiscardable() {
|
61 |
0
| this.discardable = false;
|
62 |
| } |
63 |
| |
64 |
95250
| public SimpleNode(int i) {
|
65 |
95250
| id = i;
|
66 |
| } |
67 |
| |
68 |
71018
| public SimpleNode(JavaParser p, int i) {
|
69 |
71018
| this(i);
|
70 |
71018
| parser = p;
|
71 |
| } |
72 |
| |
73 |
28864
| public void setScope(Scope scope) {
|
74 |
28864
| this.scope = scope;
|
75 |
| } |
76 |
| |
77 |
40437
| public Scope getScope() {
|
78 |
40437
| if (scope == null) {
|
79 |
28038
| return ((SimpleNode) parent).getScope();
|
80 |
| } |
81 |
12399
| return scope;
|
82 |
| } |
83 |
| |
84 |
3115
| public int getBeginLine() {
|
85 |
3115
| return beginLine;
|
86 |
| } |
87 |
| |
88 |
25237
| public void testingOnly__setBeginLine(int i) {
|
89 |
25237
| this.beginLine = i;
|
90 |
| } |
91 |
| |
92 |
45035
| public void testingOnly__setBeginColumn(int i) {
|
93 |
45035
| this.beginColumn = i;
|
94 |
| } |
95 |
| |
96 |
2728
| public int getBeginColumn() {
|
97 |
2728
| if (beginColumn != -1) {
|
98 |
2680
| return beginColumn;
|
99 |
| } else { |
100 |
48
| if ((children != null) && (children.length > 0)) {
|
101 |
48
| return ((SimpleNode) children[0]).getBeginColumn();
|
102 |
| } else { |
103 |
0
| throw new RuntimeException("Unable to determine begining line of Node.");
|
104 |
| } |
105 |
| } |
106 |
| } |
107 |
| |
108 |
29430
| public String getImage() {
|
109 |
29430
| return image;
|
110 |
| } |
111 |
| |
112 |
8755
| public void setImage(String image) {
|
113 |
8755
| this.image = image;
|
114 |
| } |
115 |
| |
116 |
2730
| public int getEndLine() {
|
117 |
2730
| return endLine;
|
118 |
| } |
119 |
| |
120 |
2680
| public int getEndColumn() {
|
121 |
2680
| return endColumn;
|
122 |
| } |
123 |
| |
124 |
27
| public Node getNthParent(int n) {
|
125 |
27
| Node result = null;
|
126 |
27
| for (int i = 0; i < n; i++) {
|
127 |
127
| if (result == null) {
|
128 |
27
| result = this.jjtGetParent();
|
129 |
| } else { |
130 |
100
| result = result.jjtGetParent();
|
131 |
| } |
132 |
| } |
133 |
27
| return result;
|
134 |
| } |
135 |
| |
136 |
| |
137 |
| |
138 |
| |
139 |
| |
140 |
| |
141 |
| |
142 |
6598
| public Node getFirstParentOfType(Class parentType) {
|
143 |
6598
| Node parentNode = jjtGetParent();
|
144 |
6598
| while (parentNode != null && parentNode.getClass() != parentType) {
|
145 |
9900
| parentNode = parentNode.jjtGetParent();
|
146 |
| } |
147 |
6598
| return parentNode;
|
148 |
| } |
149 |
| |
150 |
| |
151 |
| |
152 |
| |
153 |
| |
154 |
| |
155 |
| |
156 |
10719
| public List getParentsOfType(Class parentType) {
|
157 |
10719
| List parents = new ArrayList();
|
158 |
10719
| Node parentNode = jjtGetParent();
|
159 |
10719
| while (parentNode != null) {
|
160 |
18731
| if (parentNode.getClass() == parentType) {
|
161 |
1056
| parents.add(parentNode);
|
162 |
| } |
163 |
18731
| parentNode = parentNode.jjtGetParent();
|
164 |
| } |
165 |
10719
| return parents;
|
166 |
| } |
167 |
| |
168 |
1687
| public List findChildrenOfType(Class targetType) {
|
169 |
1687
| List list = new ArrayList();
|
170 |
1687
| findChildrenOfType(targetType, list);
|
171 |
1687
| return list;
|
172 |
| } |
173 |
| |
174 |
1710
| public void findChildrenOfType(Class targetType, List results) {
|
175 |
1710
| findChildrenOfType(this, targetType, results, true);
|
176 |
| } |
177 |
| |
178 |
45
| public void findChildrenOfType(Class targetType, List results, boolean descendIntoNestedClasses) {
|
179 |
45
| this.findChildrenOfType(this, targetType, results, descendIntoNestedClasses);
|
180 |
| } |
181 |
| |
182 |
37002
| private void findChildrenOfType(Node node, Class targetType, List results, boolean descendIntoNestedClasses) {
|
183 |
37002
| if (node.getClass().equals(targetType)) {
|
184 |
324
| results.add(node);
|
185 |
| } |
186 |
| |
187 |
37002
| if (!descendIntoNestedClasses) {
|
188 |
650
| if (node instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node).isNested()) {
|
189 |
0
| return;
|
190 |
| } |
191 |
| |
192 |
650
| if (node instanceof ASTClassOrInterfaceBodyDeclaration && ((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
|
193 |
4
| return;
|
194 |
| } |
195 |
| } |
196 |
| |
197 |
36998
| for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
198 |
46127
| Node child = node.jjtGetChild(i);
|
199 |
46127
| if (child.jjtGetNumChildren() > 0) {
|
200 |
35247
| findChildrenOfType(child, targetType, results, descendIntoNestedClasses);
|
201 |
| } else { |
202 |
10880
| if (child.getClass().equals(targetType)) {
|
203 |
135
| results.add(child);
|
204 |
| } |
205 |
| } |
206 |
| } |
207 |
| } |
208 |
| |
209 |
38930
| public void jjtSetParent(Node n) {
|
210 |
38930
| parent = n;
|
211 |
| } |
212 |
| |
213 |
139465
| public Node jjtGetParent() {
|
214 |
139465
| return parent;
|
215 |
| } |
216 |
| |
217 |
1
| public void jjtReplaceChild(Node old, Node newNode) {
|
218 |
1
| for (int i = 0; i < children.length; i++) {
|
219 |
1
| if (children[i] == old) {
|
220 |
1
| children[i] = newNode;
|
221 |
1
| return;
|
222 |
| } |
223 |
| } |
224 |
0
| throw new RuntimeException("PMD INTERNAL ERROR: SimpleNode.jjtReplaceChild called to replace a node, but couldn't find the old node");
|
225 |
| } |
226 |
| |
227 |
38951
| public void jjtAddChild(Node n, int i) {
|
228 |
38951
| if (children == null) {
|
229 |
31258
| children = new Node[i + 1];
|
230 |
7693
| } else if (i >= children.length) {
|
231 |
5
| Node c[] = new Node[i + 1];
|
232 |
5
| System.arraycopy(children, 0, c, 0, children.length);
|
233 |
5
| children = c;
|
234 |
| } |
235 |
38951
| children[i] = n;
|
236 |
| } |
237 |
| |
238 |
155846
| public Node jjtGetChild(int i) {
|
239 |
155846
| return children[i];
|
240 |
| } |
241 |
| |
242 |
274434
| public int jjtGetNumChildren() {
|
243 |
274434
| return (children == null) ? 0 : children.length;
|
244 |
| } |
245 |
| |
246 |
0
| public String toString(String prefix) {
|
247 |
0
| return prefix + toString();
|
248 |
| } |
249 |
| |
250 |
0
| public Document asXml() {
|
251 |
0
| Document document = new DocumentImpl();
|
252 |
0
| appendElement(document);
|
253 |
0
| return document;
|
254 |
| } |
255 |
| |
256 |
0
| protected void appendElement(org.w3c.dom.Node parentNode) {
|
257 |
0
| DocumentNavigator docNav = new DocumentNavigator();
|
258 |
0
| Document ownerDocument = parentNode.getOwnerDocument();
|
259 |
0
| if (ownerDocument == null) {
|
260 |
| |
261 |
0
| ownerDocument = (Document) parentNode;
|
262 |
| } |
263 |
0
| String elementName = docNav.getElementName(this);
|
264 |
0
| Element element = ownerDocument.createElement(elementName);
|
265 |
0
| parentNode.appendChild(element);
|
266 |
0
| for (Iterator iter = docNav.getAttributeAxisIterator(this); iter.hasNext();) {
|
267 |
0
| Attribute attr = (Attribute) iter.next();
|
268 |
0
| element.setAttribute(attr.getName(), attr.getValue());
|
269 |
| } |
270 |
0
| for (Iterator iter = docNav.getChildAxisIterator(this); iter.hasNext();) {
|
271 |
0
| SimpleNode child = (SimpleNode) iter.next();
|
272 |
0
| child.appendElement(element);
|
273 |
| } |
274 |
| } |
275 |
| |
276 |
| |
277 |
| |
278 |
0
| public void dump(String prefix) {
|
279 |
0
| System.out.println(toString(prefix) + (image == null ? "" : ":" + image));
|
280 |
0
| dumpChildren(prefix);
|
281 |
| } |
282 |
| |
283 |
0
| protected void dumpChildren(String prefix) {
|
284 |
0
| if (children != null) {
|
285 |
0
| for (int i = 0; i < children.length; ++i) {
|
286 |
0
| SimpleNode n = (SimpleNode) children[i];
|
287 |
0
| if (n != null) {
|
288 |
0
| n.dump(prefix + " ");
|
289 |
| } |
290 |
| } |
291 |
| } |
292 |
| } |
293 |
| |
294 |
| |
295 |
| |
296 |
| |
297 |
| |
298 |
| |
299 |
| |
300 |
| |
301 |
1727
| public Node getFirstChildOfType(Class childType) {
|
302 |
1727
| return getFirstChildOfType(childType, this);
|
303 |
| } |
304 |
| |
305 |
5548
| private Node getFirstChildOfType(Class childType, Node node) {
|
306 |
5548
| for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
307 |
5489
| Node n = node.jjtGetChild(i);
|
308 |
5489
| if (n != null) {
|
309 |
5487
| if (n.getClass().equals(childType))
|
310 |
1666
| return n;
|
311 |
3821
| Node n2 = getFirstChildOfType(childType, n);
|
312 |
3821
| if (n2 != null)
|
313 |
1560
| return n2;
|
314 |
| } |
315 |
| } |
316 |
2322
| return null;
|
317 |
| } |
318 |
| |
319 |
| |
320 |
| |
321 |
| |
322 |
| |
323 |
| |
324 |
| |
325 |
| |
326 |
8
| public final boolean containsChildOfType(Class type) {
|
327 |
8
| return !findChildrenOfType(type).isEmpty();
|
328 |
| } |
329 |
| |
330 |
9
| public List findChildNodesWithXPath(String xpathString) throws JaxenException {
|
331 |
9
| return new BaseXPath(xpathString, new DocumentNavigator()).selectNodes(this);
|
332 |
| } |
333 |
| } |
334 |
| |