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