|
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 |
| |