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