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