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