1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3   */
4   package test.net.sourceforge.pmd.ast;
5   
6   import net.sourceforge.pmd.PMD;
7   import net.sourceforge.pmd.ast.ASTBlock;
8   import net.sourceforge.pmd.ast.ASTBlockStatement;
9   import net.sourceforge.pmd.ast.ASTEqualityExpression;
10  import net.sourceforge.pmd.ast.ASTExpression;
11  import net.sourceforge.pmd.ast.ASTInstanceOfExpression;
12  import net.sourceforge.pmd.ast.ASTMethodDeclaration;
13  import net.sourceforge.pmd.ast.ASTName;
14  import net.sourceforge.pmd.ast.ASTRelationalExpression;
15  import net.sourceforge.pmd.ast.ASTReturnStatement;
16  import net.sourceforge.pmd.ast.ASTUnmodifiedClassDeclaration;
17  import net.sourceforge.pmd.ast.ASTVariableInitializer;
18  import net.sourceforge.pmd.ast.SimpleNode;
19  
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Set;
24  
25  public class SimpleNodeTest extends ParserTst {
26  
27      public void testMethodDiffLines() throws Throwable {
28          Set methods = getNodes(ASTMethodDeclaration.class, METHOD_DIFF_LINES);
29          Iterator iter = methods.iterator();
30          verifyNode((SimpleNode) iter.next(), 2, 2, 4, 2);
31      }
32  
33      public void testMethodSameLine() throws Throwable {
34          Set methods = getNodes(ASTMethodDeclaration.class, METHOD_SAME_LINE);
35          verifyNode((SimpleNode) methods.iterator().next(), 2, 2, 2, 21);
36      }
37  
38      public void testNoLookahead() throws Throwable {
39          String code = NO_LOOKAHEAD; // 1, 8 -> 1, 20
40          Set uCD = getNodes(ASTUnmodifiedClassDeclaration.class, code);
41          verifyNode((SimpleNode) uCD.iterator().next(), 1, 8, 1, 20);
42      }
43  
44      public void testHasExplicitExtends() throws Throwable {
45          String code = HAS_EXPLICIT_EXTENDS;
46          ASTUnmodifiedClassDeclaration ucd = (ASTUnmodifiedClassDeclaration)(getNodes(ASTUnmodifiedClassDeclaration.class, code).iterator().next());
47          assertTrue(ucd.hasExplicitExtends());
48      }
49  
50      public void testNoExplicitExtends() throws Throwable {
51          String code = NO_EXPLICIT_EXTENDS;
52          ASTUnmodifiedClassDeclaration ucd = (ASTUnmodifiedClassDeclaration)(getNodes(ASTUnmodifiedClassDeclaration.class, code).iterator().next());
53          assertTrue(!ucd.hasExplicitExtends());
54      }
55  
56      public void testHasExplicitImplements() throws Throwable {
57          String code = HAS_EXPLICIT_IMPLEMENTS;
58          ASTUnmodifiedClassDeclaration ucd = (ASTUnmodifiedClassDeclaration)(getNodes(ASTUnmodifiedClassDeclaration.class, code).iterator().next());
59          assertTrue(ucd.hasExplicitImplements());
60      }
61  
62      public void testNoExplicitImplements() throws Throwable {
63          String code = NO_EXPLICIT_IMPLEMENTS;
64          ASTUnmodifiedClassDeclaration ucd = (ASTUnmodifiedClassDeclaration)(getNodes(ASTUnmodifiedClassDeclaration.class, code).iterator().next());
65          assertTrue(!ucd.hasExplicitImplements());
66      }
67  
68      public void testColumnsOnQualifiedName() throws Throwable {
69          Set name = getNodes(ASTName.class, QUALIFIED_NAME);
70          Iterator i = name.iterator();
71          while (i.hasNext()) {
72              SimpleNode node = (SimpleNode) i.next();
73              if (node.getImage().equals("java.io.File")) {
74                  verifyNode(node, 1, 8, 1, 19);
75              }
76          }
77      }
78  
79      public void testLineNumbersForNameSplitOverTwoLines() throws Throwable {
80          Set name = getNodes(ASTName.class, BROKEN_LINE_IN_NAME);
81          Iterator i = name.iterator();
82          while (i.hasNext()) {
83              SimpleNode node = (SimpleNode) i.next();
84              if (node.getImage().equals("java.io.File")) {
85                  verifyNode(node, 1, 8, 2, 4);
86              }
87              if (node.getImage().equals("Foo")) {
88                  verifyNode(node, 2, 15, 2, 18);
89              }
90          }
91      }
92  
93      public void testLineNumbersAreSetOnAllSiblings() throws Throwable {
94          Set blocks = getNodes(ASTBlock.class, LINE_NUMBERS_ON_SIBLINGS);
95          Iterator i = blocks.iterator();
96          while (i.hasNext()) {
97              ASTBlock b = (ASTBlock)i.next();
98              assertTrue(b.getBeginLine() > 0);
99          }
100         blocks = getNodes(ASTVariableInitializer.class, LINE_NUMBERS_ON_SIBLINGS);
101         i = blocks.iterator();
102         while (i.hasNext()) {
103             ASTVariableInitializer b = (ASTVariableInitializer)i.next();
104             assertTrue(b.getBeginLine() > 0);
105         }
106         blocks = getNodes(ASTExpression.class, LINE_NUMBERS_ON_SIBLINGS);
107         i = blocks.iterator();
108         while (i.hasNext()) {
109             ASTExpression b = (ASTExpression)i.next();
110             assertTrue(b.getBeginLine() > 0);
111         }
112     }
113 
114     public void testFindChildrenOfType() {
115         ASTBlock block = new ASTBlock(2);
116         block.jjtAddChild(new ASTReturnStatement(1), 0);
117         assertEquals(1, block.findChildrenOfType(ASTReturnStatement.class).size());
118     }
119 
120     public void testFindChildrenOfTypeMultiple() {
121         ASTBlock block = new ASTBlock(1);
122         block.jjtAddChild(new ASTBlockStatement(2), 0);
123         block.jjtAddChild(new ASTBlockStatement(3), 1);
124         List nodes = new ArrayList();
125         block.findChildrenOfType(ASTBlockStatement.class, nodes);
126         assertEquals(2, nodes.size());
127     }
128 
129     public void testFindChildrenOfTypeRecurse() {
130         ASTBlock block = new ASTBlock(1);
131         ASTBlock childBlock = new ASTBlock(2);
132         block.jjtAddChild(childBlock, 0);
133         childBlock.jjtAddChild(new ASTMethodDeclaration(3), 0);
134         List nodes = new ArrayList();
135         block.findChildrenOfType(ASTMethodDeclaration.class, nodes);
136         assertEquals(1, nodes.size());
137     }
138 
139     public void testReplaceChild() {
140         ASTEqualityExpression ee = new ASTEqualityExpression(1);
141         ASTInstanceOfExpression io1 = new ASTInstanceOfExpression(2);
142         ASTRelationalExpression re = new ASTRelationalExpression(3);
143         ASTInstanceOfExpression io2 = new ASTInstanceOfExpression(2);
144         ee.jjtAddChild(io1, 0);
145         ee.jjtAddChild(io2, 1);
146         io1.jjtAddChild(re, 0);
147         ee.jjtReplaceChild(io1, re);
148         assertEquals(ee.jjtGetChild(0), re);
149         assertEquals(ee.jjtGetChild(1), io2);
150     }
151 
152 
153 
154     private void verifyNode(SimpleNode node, int beginLine, int beginCol, int endLine, int endCol) {
155         assertEquals("Wrong beginning line: ", beginLine, node.getBeginLine());
156         assertEquals("Wrong beginning column: ", beginCol, node.getBeginColumn());
157         assertEquals("Wrong ending line:", endLine, node.getEndLine());
158         assertEquals("Wrong ending column:", endCol, node.getEndColumn());
159     }
160 
161     private static final String HAS_EXPLICIT_EXTENDS =
162     "public class Test extends Foo {}";
163 
164     private static final String NO_EXPLICIT_EXTENDS =
165     "public class Test {}";
166 
167     private static final String HAS_EXPLICIT_IMPLEMENTS =
168     "public class Test implements Foo {}";
169 
170     private static final String NO_EXPLICIT_IMPLEMENTS =
171     "public class Test {}";
172 
173     private static final String METHOD_DIFF_LINES =
174     "public class Test {" + PMD.EOL +
175     " public void foo() {" + PMD.EOL +
176     "  int x;" + PMD.EOL +
177     " }" + PMD.EOL +
178     "}";
179 
180     private static final String METHOD_SAME_LINE =
181     "public class Test {" + PMD.EOL +
182     " public void foo() {}" + PMD.EOL +
183     "}";
184 
185     private static final String QUALIFIED_NAME =
186     "import java.io.File;" + PMD.EOL +
187     "public class Foo{}";
188 
189     private static final String BROKEN_LINE_IN_NAME =
190     "import java.io." + PMD.EOL +
191     "File;" + PMD.EOL +
192     "public class Foo{}";
193 
194     private static final String LINE_NUMBERS_ON_SIBLINGS =
195     "public class Foo {" + PMD.EOL +
196     " void bar() {" + PMD.EOL +
197     "  try {" + PMD.EOL +
198     "  } catch (Exception1 e) {" + PMD.EOL +
199     "   int x =2;" + PMD.EOL +
200     "  }" + PMD.EOL +
201     " if (x != null) {}" + PMD.EOL +
202     " }" + PMD.EOL +
203     "}";
204 
205     private static final String NO_LOOKAHEAD = "public class Foo { }";
206 }