View Javadoc

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