1
2 package net.sourceforge.pmd.ast;
3
4 import net.sourceforge.pmd.symboltable.Scope;
5
6 import java.util.ArrayList;
7 import java.util.List;
8
9 public class SimpleNode implements Node {
10
11 protected Node parent;
12 protected Node[] children;
13 protected int id;
14 protected JavaParser parser;
15 private String image;
16 private int beginLine = -1;
17 private int endLine;
18 private int beginColumn = -1;
19 private int endColumn;
20 private Scope scope;
21 private boolean discardable;
22
23 public void setDiscardable() {
24 this.discardable = true;
25 }
26
27 public void setUnDiscardable() {
28 this.discardable = false;
29 }
30
31 public boolean isDiscardable() {
32 return this.discardable;
33 }
34
35 public SimpleNode(int i) {
36 id = i;
37 }
38
39 public SimpleNode(JavaParser p, int i) {
40 this(i);
41 parser = p;
42 }
43
44 public void jjtOpen() {
45 if (beginLine == -1 && parser.token.next != null) {
46 beginLine = parser.token.next.beginLine;
47 beginColumn = parser.token.next.beginColumn;
48 }
49 }
50
51 public void jjtClose() {
52 if (beginLine == -1 && (children == null || children.length == 0)) {
53 beginColumn = parser.token.beginColumn;
54 }
55 if (beginLine == -1) {
56 beginLine = parser.token.beginLine;
57 }
58 endLine = parser.token.endLine;
59 endColumn = parser.token.endColumn;
60 }
61
62 public void setScope(Scope scope) {
63 this.scope = scope;
64 }
65
66 public Scope getScope() {
67 if (scope == null) {
68 return ((SimpleNode) parent).getScope();
69 }
70 return scope;
71 }
72
73 public int getBeginLine() {
74 return beginLine;
75 }
76
77 public void testingOnly__setBeginLine(int i) {
78 this.beginLine = i;
79 }
80
81 public void testingOnly__setBeginColumn(int i) {
82 this.beginColumn = i;
83 }
84
85 public int getBeginColumn() {
86 if (beginColumn != -1) {
87 return beginColumn;
88 } else {
89 if ((children != null) && (children.length > 0)) {
90 return ((SimpleNode) children[0]).getBeginColumn();
91 } else {
92 throw new RuntimeException("Unable to determine begining line of Node.");
93 }
94 }
95 }
96
97 public String getImage() {
98 return image;
99 }
100
101 public void setImage(String image) {
102 this.image = image;
103 }
104
105 public int getEndLine() {
106 return endLine;
107 }
108
109 public int getEndColumn() {
110 return endColumn;
111 }
112
113 /***
114 * Traverses up the tree to find the first parent instance of type parentType
115 * @param parentType class which you want to find.
116 * @return Node of type parentType. Returns null if none found.
117 */
118 public Node getFirstParentOfType(Class parentType) {
119 Node parentNode = jjtGetParent();
120 while (parentNode != null && parentNode.getClass() != parentType) {
121 parentNode = parentNode.jjtGetParent();
122 }
123 return parentNode;
124 }
125
126 /***
127 * Traverses up the tree to find all of the parent instances of type parentType
128 * @param parentType classes which you want to find.
129 * @return List of parentType instances found.
130 */
131 public List getParentsOfType(Class parentType) {
132 List parents = new ArrayList();
133 Node parentNode = jjtGetParent();
134 while (parentNode != null) {
135 if (parentNode.getClass() == parentType) {
136 parents.add(parentNode);
137 }
138 parentNode = parentNode.jjtGetParent();
139 }
140 return parents;
141 }
142
143 public List findChildrenOfType(Class targetType) {
144 List list = new ArrayList();
145 findChildrenOfType(targetType, list);
146 return list;
147 }
148
149 public void findChildrenOfType(Class targetType, List results) {
150 findChildrenOfType(this, targetType, results, true);
151 }
152
153 public void findChildrenOfType(Class targetType, List results, boolean descendIntoNestedClasses) {
154 this.findChildrenOfType(this, targetType, results, descendIntoNestedClasses);
155 }
156
157 private void findChildrenOfType(Node node, Class targetType, List results, boolean descendIntoNestedClasses) {
158 if (node.getClass().equals(targetType)) {
159 results.add(node);
160 }
161 if (node.getClass().equals(ASTNestedClassDeclaration.class) && !descendIntoNestedClasses) {
162 return;
163 }
164 if (node.getClass().equals(ASTClassBodyDeclaration.class) && ((ASTClassBodyDeclaration)node).isAnonymousInnerClass() && !descendIntoNestedClasses) {
165 return;
166 }
167 for (int i = 0; i < node.jjtGetNumChildren(); i++) {
168 Node child = node.jjtGetChild(i);
169 if (child.jjtGetNumChildren() > 0) {
170 findChildrenOfType(child, targetType, results, descendIntoNestedClasses);
171 } else {
172 if (child.getClass().equals(targetType)) {
173 results.add(child);
174 }
175 }
176 }
177 }
178
179 public void jjtSetParent(Node n) {
180 parent = n;
181 }
182
183 public Node jjtGetParent() {
184 return parent;
185 }
186
187 public void jjtReplaceChild(Node old, Node newNode) {
188 for (int i=0; i<children.length; i++) {
189 if (children[i] == old) {
190 children[i] = newNode;
191 return;
192 }
193 }
194 throw new RuntimeException("PMD INTERNAL ERROR: SimpleNode.jjtReplaceChild called to replace a node, but couldn't find the old node");
195 }
196
197 public void jjtAddChild(Node n, int i) {
198 if (children == null) {
199 children = new Node[i + 1];
200 } else if (i >= children.length) {
201 Node c[] = new Node[i + 1];
202 System.arraycopy(children, 0, c, 0, children.length);
203 children = c;
204 }
205 children[i] = n;
206 }
207
208 public Node jjtGetChild(int i) {
209 return children[i];
210 }
211
212 public int jjtGetNumChildren() {
213 return (children == null) ? 0 : children.length;
214 }
215
216 /*** Accept the visitor. **/
217 public Object jjtAccept(JavaParserVisitor visitor, Object data) {
218 return visitor.visit(this, data);
219 }
220
221 /*** Accept the visitor. **/
222 public Object childrenAccept(JavaParserVisitor visitor, Object data) {
223 if (children != null) {
224 for (int i = 0; i < children.length; ++i) {
225 children[i].jjtAccept(visitor, data);
226 }
227 }
228 return data;
229 }
230
231
232
233
234
235
236
237 public String toString() {
238 return JavaParserTreeConstants.jjtNodeName[id];
239 }
240
241 public String toString(String prefix) {
242 return prefix + toString();
243 }
244
245
246
247 public void dump(String prefix) {
248 System.out.println(toString(prefix));
249 dumpChildren(prefix);
250 }
251
252 protected void dumpChildren(String prefix) {
253 if (children != null) {
254 for (int i = 0; i < children.length; ++i) {
255 SimpleNode n = (SimpleNode) children[i];
256 if (n != null) {
257 n.dump(prefix + " ");
258 }
259 }
260 }
261 }
262
263 }
264