|
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.jaxen.BaseXPath; |
|
9 |
| import org.jaxen.JaxenException; |
|
10 |
| import org.w3c.dom.Document; |
|
11 |
| import org.w3c.dom.Element; |
|
12 |
| |
|
13 |
| import javax.xml.parsers.DocumentBuilderFactory; |
|
14 |
| import javax.xml.parsers.DocumentBuilder; |
|
15 |
| import javax.xml.parsers.ParserConfigurationException; |
|
16 |
| import java.util.ArrayList; |
|
17 |
| import java.util.Iterator; |
|
18 |
| import java.util.List; |
|
19 |
| |
|
20 |
| public abstract class SimpleNode implements Node { |
|
21 |
| |
|
22 |
| protected Node parent; |
|
23 |
| protected Node[] children; |
|
24 |
| protected int id; |
|
25 |
| protected JavaParser parser; |
|
26 |
| private String image; |
|
27 |
| protected int beginLine = -1; |
|
28 |
| protected int endLine; |
|
29 |
| protected int beginColumn = -1; |
|
30 |
| protected int endColumn; |
|
31 |
| private Scope scope; |
|
32 |
| private IDataFlowNode dataFlowNode; |
|
33 |
| |
|
34 |
127
| public IDataFlowNode getDataFlowNode() {
|
|
35 |
127
| if (this.dataFlowNode == null) {
|
|
36 |
37
| if (this.parent != null) {
|
|
37 |
37
| return ((SimpleNode) parent).getDataFlowNode();
|
|
38 |
| } |
|
39 |
0
| return null;
|
|
40 |
| } |
|
41 |
90
| return dataFlowNode;
|
|
42 |
| } |
|
43 |
| |
|
44 |
230
| public void setDataFlowNode(IDataFlowNode dataFlowNode) {
|
|
45 |
230
| this.dataFlowNode = dataFlowNode;
|
|
46 |
| } |
|
47 |
| |
|
48 |
108659
| public SimpleNode(int i) {
|
|
49 |
108659
| id = i;
|
|
50 |
| } |
|
51 |
| |
|
52 |
84409
| public SimpleNode(JavaParser p, int i) {
|
|
53 |
84409
| this(i);
|
|
54 |
84409
| parser = p;
|
|
55 |
| } |
|
56 |
| |
|
57 |
29745
| public void setScope(Scope scope) {
|
|
58 |
29745
| this.scope = scope;
|
|
59 |
| } |
|
60 |
| |
|
61 |
48289
| public Scope getScope() {
|
|
62 |
48289
| if (scope == null) {
|
|
63 |
34195
| return ((SimpleNode) parent).getScope();
|
|
64 |
| } |
|
65 |
14094
| return scope;
|
|
66 |
| } |
|
67 |
| |
|
68 |
3219
| public int getBeginLine() {
|
|
69 |
3219
| return beginLine;
|
|
70 |
| } |
|
71 |
| |
|
72 |
| |
|
73 |
| |
|
74 |
| |
|
75 |
0
| public String getLabel() {
|
|
76 |
0
| return null;
|
|
77 |
| } |
|
78 |
| |
|
79 |
207
| public boolean hasImageEqualTo(String arg) {
|
|
80 |
207
| return image != null && image.equals(arg);
|
|
81 |
| } |
|
82 |
| |
|
83 |
25605
| public void testingOnly__setBeginLine(int i) {
|
|
84 |
25605
| this.beginLine = i;
|
|
85 |
| } |
|
86 |
| |
|
87 |
45403
| public void testingOnly__setBeginColumn(int i) {
|
|
88 |
45403
| this.beginColumn = i;
|
|
89 |
| } |
|
90 |
| |
|
91 |
2900
| public int getBeginColumn() {
|
|
92 |
2900
| if (beginColumn != -1) {
|
|
93 |
2900
| return beginColumn;
|
|
94 |
| } else { |
|
95 |
0
| if ((children != null) && (children.length > 0)) {
|
|
96 |
0
| return ((SimpleNode) children[0]).getBeginColumn();
|
|
97 |
| } else { |
|
98 |
0
| throw new RuntimeException("Unable to determine begining line of Node.");
|
|
99 |
| } |
|
100 |
| } |
|
101 |
| } |
|
102 |
| |
|
103 |
34388
| public String getImage() {
|
|
104 |
34388
| return image;
|
|
105 |
| } |
|
106 |
| |
|
107 |
10338
| public void setImage(String image) {
|
|
108 |
10338
| this.image = image;
|
|
109 |
| } |
|
110 |
| |
|
111 |
2955
| public int getEndLine() {
|
|
112 |
2955
| return endLine;
|
|
113 |
| } |
|
114 |
| |
|
115 |
2900
| public int getEndColumn() {
|
|
116 |
2900
| return endColumn;
|
|
117 |
| } |
|
118 |
| |
|
119 |
27
| public Node getNthParent(int n) {
|
|
120 |
27
| Node result = null;
|
|
121 |
27
| for (int i = 0; i < n; i++) {
|
|
122 |
127
| if (result == null) {
|
|
123 |
27
| result = this.jjtGetParent();
|
|
124 |
| } else { |
|
125 |
100
| result = result.jjtGetParent();
|
|
126 |
| } |
|
127 |
| } |
|
128 |
27
| return result;
|
|
129 |
| } |
|
130 |
| |
|
131 |
| |
|
132 |
| |
|
133 |
| |
|
134 |
| |
|
135 |
| |
|
136 |
| |
|
137 |
7224
| public Node getFirstParentOfType(Class parentType) {
|
|
138 |
7224
| Node parentNode = jjtGetParent();
|
|
139 |
7224
| while (parentNode != null && parentNode.getClass() != parentType) {
|
|
140 |
11976
| parentNode = parentNode.jjtGetParent();
|
|
141 |
| } |
|
142 |
7224
| return parentNode;
|
|
143 |
| } |
|
144 |
| |
|
145 |
| |
|
146 |
| |
|
147 |
| |
|
148 |
| |
|
149 |
| |
|
150 |
| |
|
151 |
11599
| public List getParentsOfType(Class parentType) {
|
|
152 |
11599
| List parents = new ArrayList();
|
|
153 |
11599
| Node parentNode = jjtGetParent();
|
|
154 |
11599
| while (parentNode != null) {
|
|
155 |
22963
| if (parentNode.getClass() == parentType) {
|
|
156 |
1298
| parents.add(parentNode);
|
|
157 |
| } |
|
158 |
22963
| parentNode = parentNode.jjtGetParent();
|
|
159 |
| } |
|
160 |
11599
| return parents;
|
|
161 |
| } |
|
162 |
| |
|
163 |
2639
| public List findChildrenOfType(Class targetType) {
|
|
164 |
2639
| List list = new ArrayList();
|
|
165 |
2639
| findChildrenOfType(targetType, list);
|
|
166 |
2639
| return list;
|
|
167 |
| } |
|
168 |
| |
|
169 |
2662
| public void findChildrenOfType(Class targetType, List results) {
|
|
170 |
2662
| findChildrenOfType(this, targetType, results, true);
|
|
171 |
| } |
|
172 |
| |
|
173 |
58
| public void findChildrenOfType(Class targetType, List results, boolean descendIntoNestedClasses) {
|
|
174 |
58
| this.findChildrenOfType(this, targetType, results, descendIntoNestedClasses);
|
|
175 |
| } |
|
176 |
| |
|
177 |
47835
| private void findChildrenOfType(Node node, Class targetType, List results, boolean descendIntoNestedClasses) {
|
|
178 |
47835
| if (node.getClass().equals(targetType)) {
|
|
179 |
383
| results.add(node);
|
|
180 |
| } |
|
181 |
| |
|
182 |
47835
| if (!descendIntoNestedClasses) {
|
|
183 |
650
| if (node instanceof ASTClassOrInterfaceDeclaration && ((ASTClassOrInterfaceDeclaration) node).isNested()) {
|
|
184 |
0
| return;
|
|
185 |
| } |
|
186 |
| |
|
187 |
650
| if (node instanceof ASTClassOrInterfaceBodyDeclaration && ((ASTClassOrInterfaceBodyDeclaration) node).isAnonymousInnerClass()) {
|
|
188 |
4
| return;
|
|
189 |
| } |
|
190 |
| } |
|
191 |
| |
|
192 |
47831
| for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
|
193 |
59246
| Node child = node.jjtGetChild(i);
|
|
194 |
59246
| if (child.jjtGetNumChildren() > 0) {
|
|
195 |
45115
| findChildrenOfType(child, targetType, results, descendIntoNestedClasses);
|
|
196 |
| } else { |
|
197 |
14131
| if (child.getClass().equals(targetType)) {
|
|
198 |
626
| results.add(child);
|
|
199 |
| } |
|
200 |
| } |
|
201 |
| } |
|
202 |
| } |
|
203 |
| |
|
204 |
46133
| public void jjtSetParent(Node n) {
|
|
205 |
46133
| parent = n;
|
|
206 |
| } |
|
207 |
| |
|
208 |
103190
| public Node jjtGetParent() {
|
|
209 |
103190
| return parent;
|
|
210 |
| } |
|
211 |
| |
|
212 |
46143
| public void jjtAddChild(Node n, int i) {
|
|
213 |
46143
| if (children == null) {
|
|
214 |
37070
| children = new Node[i + 1];
|
|
215 |
9073
| } else if (i >= children.length) {
|
|
216 |
4
| Node c[] = new Node[i + 1];
|
|
217 |
4
| System.arraycopy(children, 0, c, 0, children.length);
|
|
218 |
4
| children = c;
|
|
219 |
| } |
|
220 |
46143
| children[i] = n;
|
|
221 |
| } |
|
222 |
| |
|
223 |
123406
| public Node jjtGetChild(int i) {
|
|
224 |
123406
| return children[i];
|
|
225 |
| } |
|
226 |
| |
|
227 |
242997
| public int jjtGetNumChildren() {
|
|
228 |
242997
| return (children == null) ? 0 : children.length;
|
|
229 |
| } |
|
230 |
| |
|
231 |
0
| public String toString(String prefix) {
|
|
232 |
0
| return prefix + toString();
|
|
233 |
| } |
|
234 |
| |
|
235 |
0
| public Document asXml() {
|
|
236 |
0
| try {
|
|
237 |
0
| DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
|
238 |
0
| DocumentBuilder db = dbf.newDocumentBuilder();
|
|
239 |
0
| Document document = db.newDocument();
|
|
240 |
0
| appendElement(document);
|
|
241 |
0
| return document;
|
|
242 |
| } catch (ParserConfigurationException pce) { |
|
243 |
0
| throw new RuntimeException(pce);
|
|
244 |
| } |
|
245 |
| } |
|
246 |
| |
|
247 |
0
| protected void appendElement(org.w3c.dom.Node parentNode) {
|
|
248 |
0
| DocumentNavigator docNav = new DocumentNavigator();
|
|
249 |
0
| Document ownerDocument = parentNode.getOwnerDocument();
|
|
250 |
0
| if (ownerDocument == null) {
|
|
251 |
| |
|
252 |
0
| ownerDocument = (Document) parentNode;
|
|
253 |
| } |
|
254 |
0
| String elementName = docNav.getElementName(this);
|
|
255 |
0
| Element element = ownerDocument.createElement(elementName);
|
|
256 |
0
| parentNode.appendChild(element);
|
|
257 |
0
| for (Iterator iter = docNav.getAttributeAxisIterator(this); iter.hasNext();) {
|
|
258 |
0
| Attribute attr = (Attribute) iter.next();
|
|
259 |
0
| element.setAttribute(attr.getName(), attr.getValue());
|
|
260 |
| } |
|
261 |
0
| for (Iterator iter = docNav.getChildAxisIterator(this); iter.hasNext();) {
|
|
262 |
0
| SimpleNode child = (SimpleNode) iter.next();
|
|
263 |
0
| child.appendElement(element);
|
|
264 |
| } |
|
265 |
| } |
|
266 |
| |
|
267 |
| |
|
268 |
| |
|
269 |
0
| public void dump(String prefix) {
|
|
270 |
0
| System.out.println(toString(prefix) + (image == null ? "" : ":" + image));
|
|
271 |
0
| dumpChildren(prefix);
|
|
272 |
| } |
|
273 |
| |
|
274 |
0
| protected void dumpChildren(String prefix) {
|
|
275 |
0
| if (children != null) {
|
|
276 |
0
| for (int i = 0; i < children.length; ++i) {
|
|
277 |
0
| SimpleNode n = (SimpleNode) children[i];
|
|
278 |
0
| if (n != null) {
|
|
279 |
0
| n.dump(prefix + " ");
|
|
280 |
| } |
|
281 |
| } |
|
282 |
| } |
|
283 |
| } |
|
284 |
| |
|
285 |
| |
|
286 |
| |
|
287 |
| |
|
288 |
| |
|
289 |
| |
|
290 |
| |
|
291 |
| |
|
292 |
2175
| public Node getFirstChildOfType(Class childType) {
|
|
293 |
2175
| return getFirstChildOfType(childType, this);
|
|
294 |
| } |
|
295 |
| |
|
296 |
7568
| private Node getFirstChildOfType(Class childType, Node node) {
|
|
297 |
7568
| for (int i = 0; i < node.jjtGetNumChildren(); i++) {
|
|
298 |
7454
| Node n = node.jjtGetChild(i);
|
|
299 |
7454
| if (n != null) {
|
|
300 |
7452
| if (n.getClass().equals(childType))
|
|
301 |
2059
| return n;
|
|
302 |
5393
| Node n2 = getFirstChildOfType(childType, n);
|
|
303 |
5393
| if (n2 != null)
|
|
304 |
1894
| return n2;
|
|
305 |
| } |
|
306 |
| } |
|
307 |
3615
| return null;
|
|
308 |
| } |
|
309 |
| |
|
310 |
| |
|
311 |
| |
|
312 |
| |
|
313 |
| |
|
314 |
| |
|
315 |
| |
|
316 |
| |
|
317 |
14
| public final boolean containsChildOfType(Class type) {
|
|
318 |
14
| return !findChildrenOfType(type).isEmpty();
|
|
319 |
| } |
|
320 |
| |
|
321 |
7
| public List findChildNodesWithXPath(String xpathString) throws JaxenException {
|
|
322 |
7
| return new BaseXPath(xpathString, new DocumentNavigator()).selectNodes(this);
|
|
323 |
| } |
|
324 |
| } |