Structure.java
01 /**
02  * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03  */
04 package net.sourceforge.pmd.lang.dfa;
05 
06 import java.util.ArrayList;
07 import java.util.List;
08 import java.util.Stack;
09 
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 }