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  }