View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.lang.dfa;
    5
    6   import java.util.ArrayList;
    7   import java.util.List;
    8   import java.util.Stack;
    9
    10  import net.sourceforge.pmd.lang.DataFlowHandler;
    11  import net.sourceforge.pmd.lang.ast.Node;
    12
    13  /**
    14   * @author raik
    15   *         <p/>
    16   *         Structure contains only raw data. A set of nodes which represent a data flow
    17   *         and 2 stacks to link the nodes to each other.
    18   */
    19  public class Structure {
    20
    21      private final DataFlowHandler dataFlowHandler;
    22      private List<DataFlowNode> dataFlow = new ArrayList<DataFlowNode>();
    23      private Stack<StackObject> braceStack = new Stack<StackObject>();
    24      private Stack<StackObject> continueBreakReturnStack = new Stack<StackObject>();
    25
    26      public Structure(DataFlowHandler dataFlowHandler) {
    27  	this.dataFlowHandler = dataFlowHandler;
    28      }
    29
    30      /**
    31       * This class encapsulates the access to the DataFlowNode class. Is this worthwhile?
    32       * TODO I think it's too confusing to have the DataFlowNode constructor
    33       * add the created instance to the List.  I think it'd be clearer if we did
    34       * that more "procedurally", i.e., create the object, then add it to the list.
    35       */
    36      public DataFlowNode createNewNode(Node node) {
    37  	return dataFlowHandler.createDataFlowNode(dataFlow, node);
    38      }
    39
    40      public DataFlowNode createStartNode(int line) {
    41  	return new StartOrEndDataFlowNode(this.dataFlow, line, true);
    42      }
    43
    44      public DataFlowNode createEndNode(int line) {
    45  	return new StartOrEndDataFlowNode(this.dataFlow, line, false);
    46      }
    47
    48      public DataFlowNode getLast() {
    49  	return this.dataFlow.get(this.dataFlow.size() - 1);
    50      }
    51
    52      public DataFlowNode getFirst() {
    53  	return this.dataFlow.get(0);
    54      }
    55
    56      //  ----------------------------------------------------------------------------
    57      //	STACK FUNCTIONS
    58
    59      /**
    60       * The braceStack contains all nodes which are important to link the data
    61       * flow nodes. The cbrStack contains continue, break, and return nodes.
    62       * There are 2 Stacks because the have to process differently.
    63       */
    64      public void pushOnStack(int type, DataFlowNode node) {
    65  	StackObject obj = new StackObject(type, node);
    66  	if (type == NodeType.RETURN_STATEMENT || type == NodeType.BREAK_STATEMENT
    67  		|| type == NodeType.CONTINUE_STATEMENT || type == NodeType.THROW_STATEMENT) {
    68  	    // ugly solution - stores the type information in two ways
    69  	    continueBreakReturnStack.push(obj);
    70  	} else {
    71  	    braceStack.push(obj);
    72  	}
    73  	node.setType(type);
    74      }
    75
    76      public List<StackObject> getBraceStack() {
    77  	return braceStack;
    78      }
    79
    80      public List<StackObject> getContinueBreakReturnStack() {
    81  	return continueBreakReturnStack;
    82      }
    83
    84  }