View Javadoc

1   package net.sourceforge.pmd.lang.plsql.dfa;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertTrue;
5   
6   import java.util.List;
7   
8   import net.sourceforge.pmd.PMD;
9   import net.sourceforge.pmd.lang.Language;
10  import net.sourceforge.pmd.lang.dfa.DataFlowNode;
11  import net.sourceforge.pmd.lang.dfa.NodeType;
12  import net.sourceforge.pmd.lang.dfa.StartOrEndDataFlowNode;
13  import net.sourceforge.pmd.lang.plsql.AbstractPLSQLParserTst;
14  import net.sourceforge.pmd.lang.plsql.ast.ASTExpression;
15  import net.sourceforge.pmd.lang.plsql.ast.ASTMethodDeclaration;
16  import net.sourceforge.pmd.lang.plsql.ast.ASTProgramUnit;
17  import net.sourceforge.pmd.lang.plsql.ast.ASTVariableOrConstantDeclarator;
18  
19  import org.junit.Test;
20  
21  
22  public class StatementAndBraceFinderTest extends AbstractPLSQLParserTst {
23  
24      /**Java ASTStatementExpression equivalent is inferred as an Expression() which has
25       * an UnlabelledStatement as a parent.
26       * 
27       * @throws Throwable 
28       */
29      @Test
30      public void testExpressionParentChildLinks() throws Throwable {
31          ASTExpression ex = getOrderedNodes(ASTExpression.class, TEST1).get(0);
32          DataFlowNode dfn = ex.getDataFlowNode();
33          assertEquals(3, dfn.getLine());
34          assertTrue(dfn.getNode() instanceof ASTExpression);
35          List<DataFlowNode> dfns = dfn.getParents();
36          assertEquals(1, dfns.size());
37          DataFlowNode parentDfn =  dfns.get(0);
38          assertEquals(2, parentDfn.getLine());
39          assertTrue(parentDfn.getNode() instanceof ASTProgramUnit);
40          ASTProgramUnit exParent = (ASTProgramUnit) parentDfn.getNode();
41         //Validate the two-way link betwen Program Unit and Statement 
42          assertEquals(ex, exParent.getDataFlowNode().getChildren().get(0).getNode());
43          assertEquals(exParent, ex.getDataFlowNode().getParents().get(0).getNode());
44      }
45  
46      @Test
47      public void testVariableOrConstantDeclaratorParentChildLinks() throws Throwable {
48          ASTVariableOrConstantDeclarator vd = getOrderedNodes(ASTVariableOrConstantDeclarator.class, TEST2).get(0);
49          //ASTMethodDeclaration vdParent = (ASTMethodDeclaration) ((DataFlowNode) vd.getDataFlowNode().getParents().get(0)).getNode();
50          ASTProgramUnit vdParent = (ASTProgramUnit) vd.getDataFlowNode().getParents().get(0).getNode();
51          //Validate the two-way link betwen Program Unit and Variable 
52          assertEquals(vd, vdParent.getDataFlowNode().getChildren().get(0).getNode());
53          assertEquals(vdParent, vd.getDataFlowNode().getParents().get(0).getNode());
54      }
55  
56      @Test
57      public void testIfStmtHasCorrectTypes() throws Throwable {
58          ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST3).get(0);
59          assertEquals(5, exp.getDataFlowNode().getFlow().size());
60          DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2);
61          assertTrue(dfn.isType(NodeType.IF_EXPR));
62          assertEquals(3, dfn.getLine());
63          dfn = exp.getDataFlowNode().getFlow().get(3);
64          assertTrue(dfn.isType(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE));
65          assertEquals(3, dfn.getLine());
66      }
67  
68      @Test
69      public void testWhileStmtHasCorrectTypes() throws Throwable {
70          ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST4).get(0);
71          DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2);
72          assertTrue(dfn.isType(NodeType.WHILE_EXPR));
73          dfn = exp.getDataFlowNode().getFlow().get(3);
74          assertTrue(dfn.isType(NodeType.WHILE_LAST_STATEMENT));
75      }
76  
77      @Test
78      public void testForStmtHasCorrectTypes() throws Throwable {
79          ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST5).get(0);
80          DataFlowNode dfn = null;
81          dfn = exp.getDataFlowNode().getFlow().get(0);
82          assertTrue(dfn instanceof StartOrEndDataFlowNode);
83          dfn = exp.getDataFlowNode().getFlow().get(1);
84          assertTrue(dfn.getNode() instanceof ASTProgramUnit);
85          assertEquals(2, dfn.getLine());
86          dfn = exp.getDataFlowNode().getFlow().get(2);
87          assertEquals(3, dfn.getLine());
88          assertTrue(dfn.isType(NodeType.FOR_EXPR));
89          assertTrue(dfn.isType(NodeType.FOR_BEFORE_FIRST_STATEMENT));
90          dfn = exp.getDataFlowNode().getFlow().get(3);
91          assertEquals(3, dfn.getLine());
92          assertTrue(dfn.isType(NodeType.FOR_END));
93      }
94  
95      @Test
96      public void testSimpleCaseStmtHasCorrectTypes() throws Throwable {
97          ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST6).get(0);
98          DataFlowNode dfn = null;
99          dfn = exp.getDataFlowNode().getFlow().get(0);
100         assertTrue(dfn instanceof StartOrEndDataFlowNode);
101         dfn = exp.getDataFlowNode().getFlow().get(1);
102         assertEquals(2, dfn.getLine());
103         assertTrue(dfn.getNode() instanceof ASTProgramUnit);
104         dfn = exp.getDataFlowNode().getFlow().get(2);
105         assertEquals(4, dfn.getLine());
106         assertTrue(dfn.isType(NodeType.SWITCH_START));
107         assertTrue(dfn.isType(NodeType.CASE_LAST_STATEMENT));
108         dfn = exp.getDataFlowNode().getFlow().get(3);
109         assertEquals(5, dfn.getLine());
110         assertTrue(dfn.isType(NodeType.CASE_LAST_STATEMENT));
111         assertTrue(dfn.isType(NodeType.BREAK_STATEMENT));
112         dfn = exp.getDataFlowNode().getFlow().get(4);
113         assertEquals(6, dfn.getLine());
114         assertTrue(dfn.isType(NodeType.SWITCH_LAST_DEFAULT_STATEMENT));
115         assertTrue(dfn.isType(NodeType.BREAK_STATEMENT));
116         dfn = exp.getDataFlowNode().getFlow().get(5);
117         assertEquals(7, dfn.getLine());
118         assertTrue(dfn.isType(NodeType.SWITCH_END));
119     }
120 
121 /*
122     @Test
123     public void testSearchedCaseStmtHasCorrectTypes() throws Throwable {
124         List<ASTStatement> statements =  getOrderedNodes(ASTStatement.class, TEST7);
125         List<ASTExpression> expressions =  getOrderedNodes(ASTExpression.class, TEST7);
126 
127         ASTStatement st = statements.get(0);
128         ASTStatement st1 = statements.get(1);
129         ASTStatement st2 = statements.get(2);
130         ASTStatement st3 = statements.get(3);
131         System.err.println("testSearchedCaseStmtHasCorrectTypes-st(0)="+st.getBeginLine()); 
132 
133         ASTExpression ex = expressions.get(0);
134         ASTExpression ex1 = expressions.get(1);
135         ASTExpression ex2 = expressions.get(2);
136         ASTExpression ex3 = expressions.get(3);
137         ASTExpression ex4 = expressions.get(4);
138         System.err.println("ASTExpression="+ex );
139 
140         DataFlowNode dfn = null;
141         //dfn = ex.getDataFlowNode().getFlow().get(0);
142         //dfn = st.getDataFlowNode().getFlow().get(0);
143         dfn = (DataFlowNode) st.getDataFlowNode();
144         System.err.println("DataFlowNode(st-0)="+dfn ) ;
145         System.err.println("DataFlowNode(st-1)="+st1.getDataFlowNode() ) ;
146         System.err.println("DataFlowNode(st-2)="+st2.getDataFlowNode() ) ;
147         System.err.println("DataFlowNode(st-3)="+st3.getDataFlowNode() ) ;
148 
149         System.err.println("DataFlowNode(ex-0)="+ex.getDataFlowNode() ) ;
150         System.err.println("DataFlowNode(ex-1)="+ex1.getDataFlowNode() ) ;
151         System.err.println("DataFlowNode(ex-2)="+ex2.getDataFlowNode() ) ;
152         System.err.println("DataFlowNode(ex-3)="+ex3.getDataFlowNode() ) ;
153         System.err.println("DataFlowNode(ex-4)="+ex4.getDataFlowNode() ) ;
154         List<DataFlowNode> dfns = dfn.getFlow();
155         System.err.println("DataFlowNodes List size="+dfns.size()) ;
156         DataFlowNode firstDfn =  dfns.get(0);
157         System.err.println("firstDataFlowNode="+firstDfn ) ;
158         System.err.println("testSearchedCaseStmtHasCorrectTypes-dfn(0)="+dfn);
159         dfn = st.getDataFlowNode().getFlow().get(1);
160         System.err.println("testSearchedCaseStmtHasCorrectTypes-dfn(1)="+dfn);
161         dfn = st.getDataFlowNode().getFlow().get(2);
162         System.err.println("testSearchedCaseStmtHasCorrectTypes-dfn(2)="+dfn);
163         assertTrue(dfn.isType(NodeType.SWITCH_START));
164         dfn = st.getDataFlowNode().getFlow().get(3);
165         System.err.println("testSearchedCaseStmtHasCorrectTypes-dfn(3)="+dfn);
166         assertTrue(dfn.isType(NodeType.CASE_LAST_STATEMENT));
167         //dfn = st.getDataFlowNode().getFlow().get(4);
168         System.err.println("testSearchedCaseStmtHasCorrectTypes-dfn(5)="+dfn);
169         assertTrue(dfn.isType(NodeType.CASE_LAST_STATEMENT));
170         dfn = st.getDataFlowNode().getFlow().get(5);
171         System.err.println("testSearchedCaseStmtHasCorrectTypes-dfn(7)="+dfn);
172         assertTrue(dfn.isType(NodeType.SWITCH_LAST_DEFAULT_STATEMENT));
173         dfn = st.getDataFlowNode().getFlow().get(6);
174         System.err.println("testSearchedCaseStmtHasCorrectTypes-dfn(8)="+dfn);
175         assertTrue(dfn.isType(NodeType.SWITCH_END));
176     }
177 */
178     @Test
179     public void testLabelledStmtHasCorrectTypes() throws Throwable {
180         ASTExpression exp = getOrderedNodes(ASTExpression.class, TEST8).get(0);
181         DataFlowNode dfn = exp.getDataFlowNode().getFlow().get(2);
182         assertEquals(3, dfn.getLine());
183         assertTrue(dfn.isType(NodeType.LABEL_STATEMENT));
184     }
185 
186     @Test(expected = RuntimeException.class)
187     public void testOnlyWorksForMethodsAndConstructors() {
188         StatementAndBraceFinder sbf = new StatementAndBraceFinder(Language.PLSQL.getDefaultVersion().getLanguageVersionHandler().getDataFlowHandler());
189         sbf.buildDataFlowFor(new ASTMethodDeclaration(1));
190         //sbf.buildDataFlowFor(new ASTConstructorDeclaration(1));
191         sbf.buildDataFlowFor(new ASTProgramUnit(1));
192     }
193 
194     private static final String TEST1 =
195             "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
196             " PROCEDURE bar IS BEGIN" + PMD.EOL +
197             "  x := 2;" + PMD.EOL +
198             " END bar;" + PMD.EOL +
199             "END foo;";
200 
201     private static final String TEST2 =
202             "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
203             " PROCEDURE bar IS " + PMD.EOL +
204             "  int x; " + PMD.EOL +
205 	    "  BEGIN NULL ;" + PMD.EOL +
206             " END bar;" + PMD.EOL +
207             "END foo;";
208 
209     private static final String TEST3 =
210            "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
211             " PROCEDURE bar IS BEGIN" + PMD.EOL +
212             "  if (x) THEN NULL; END IF; " + PMD.EOL +
213             " END bar;" + PMD.EOL +
214             "END foo;";
215 
216     private static final String TEST4 =
217             "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
218             " PROCEDURE bar IS BEGIN" + PMD.EOL +
219             "  while (x) LOOP NULL; END LOOP;" + PMD.EOL +
220             " END bar;" + PMD.EOL +
221             "END foo;";
222 
223     private static final String TEST5 =
224             "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
225             " PROCEDURE bar IS BEGIN" + PMD.EOL +
226             "  for i in 0..9 LOOP NULL; END LOOP;" + PMD.EOL +
227             " END bar;" + PMD.EOL +
228             "END foo;";
229 
230     private static final String TEST6 =
231             "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
232             " PROCEDURE bar IS " + PMD.EOL +
233             " BEGIN" + PMD.EOL +
234             " CASE 1 " + PMD.EOL +
235             " WHEN 0 THEN NULL; "+ PMD.EOL +
236             " WHEN 1 THEN NULL; " + PMD.EOL +
237             " ELSE NULL;" + PMD.EOL +
238             " END CASE; " + PMD.EOL +
239             " END bar; " + PMD.EOL +
240             "END foo;";
241 
242     private static final String TEST7 =
243             "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
244             " PROCEDURE bar IS " + PMD.EOL +
245             " BEGIN" + PMD.EOL +
246             " CASE "+ PMD.EOL +
247             " WHEN 0=1 THEN NULL; "+ PMD.EOL +
248             " WHEN 1=1 THEN NULL; "+ PMD.EOL +
249             " ELSE NULL;" + PMD.EOL +
250             " END CASE;" + PMD.EOL +
251             " END bar;" + PMD.EOL +
252             "END foo;";
253 
254     private static final String TEST8 =
255             "CREATE OR REPLACE PACKAGE BODY Foo AS" + PMD.EOL +
256             " PROCEDURE bar IS BEGIN" + PMD.EOL +
257             " <<label>> NULL;" + PMD.EOL +
258             " END bar;" + PMD.EOL +
259             "END foo;";
260 
261     public static junit.framework.Test suite() {
262         return new junit.framework.JUnit4TestAdapter(StatementAndBraceFinderTest.class);
263     }
264 }