1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package test.net.sourceforge.pmd.symboltable;
5   
6   import static org.junit.Assert.assertEquals;
7   import static org.junit.Assert.assertFalse;
8   import static org.junit.Assert.assertTrue;
9   import net.sourceforge.pmd.PMD;
10  import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
11  import net.sourceforge.pmd.ast.ASTMethodDeclaration;
12  import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
13  import net.sourceforge.pmd.ast.SimpleJavaNode;
14  import net.sourceforge.pmd.ast.SimpleNode;
15  import net.sourceforge.pmd.symboltable.ClassNameDeclaration;
16  import net.sourceforge.pmd.symboltable.ClassScope;
17  import net.sourceforge.pmd.symboltable.MethodNameDeclaration;
18  import net.sourceforge.pmd.symboltable.NameOccurrence;
19  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
20  
21  import org.junit.Test;
22  
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  public class ClassScopeTest extends STBBaseTst {
27  
28      @Test
29      public void testEnumsClassScope() {
30          parseCode15(ENUM_SCOPE);
31      }
32  
33      // FIXME - these will break when this goes from Anonymous$1 to Foo$1
34      @Test
35      public void testAnonymousInnerClassName() {
36          ClassScope s = new ClassScope();
37          assertEquals("Anonymous$1", s.getClassName());
38          s = new ClassScope();
39          assertEquals("Anonymous$2", s.getClassName());
40      }
41  
42      @Test
43      public void testContains() {
44          ClassScope s = new ClassScope("Foo");
45          ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
46          node.setImage("bar");
47          s.addDeclaration(new VariableNameDeclaration(node));
48          assertTrue(s.getVariableDeclarations().keySet().iterator().hasNext());
49      }
50  
51      @Test
52      public void testCantContainsSuperToString() {
53          ClassScope s = new ClassScope("Foo");
54          SimpleNode node = new SimpleJavaNode(1);
55          node.setImage("super.toString");
56          assertFalse(s.contains(new NameOccurrence(node, node.getImage())));
57      }
58  
59      @Test
60      public void testContainsStaticVariablePrefixedWithClassName() {
61          ClassScope s = new ClassScope("Foo");
62          ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
63          node.setImage("X");
64          s.addDeclaration(new VariableNameDeclaration(node));
65  
66          SimpleNode node2 = new SimpleJavaNode(2);
67          node2.setImage("Foo.X");
68          assertTrue(s.contains(new NameOccurrence(node2, node2.getImage())));
69      }
70  
71      @Test
72      public void testClassName() {
73          parseCode(CLASS_NAME);
74          ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
75          assertEquals("Foo", n.getScope().getEnclosingClassScope().getClassName());
76      }
77  
78      @Test
79      public void testMethodDeclarationRecorded() {
80          parseCode(METHOD_DECLARATIONS_RECORDED);
81          ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
82          ClassScope s = (ClassScope) n.getScope();
83          Map m = s.getMethodDeclarations();
84          assertEquals(1, m.size());
85          MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
86          assertEquals("bar", mnd.getImage());
87          ASTMethodDeclaration node = (ASTMethodDeclaration) mnd.getNode().jjtGetParent();
88          assertTrue(node.isPrivate());
89      }
90  
91      @Test
92      public void testTwoMethodsSameNameDiffArgs() {
93          // TODO this won't work with String and java.lang.String
94          parseCode(METHODS_WITH_DIFF_ARG);
95          ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
96          Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
97          assertEquals(2, m.size());
98          Iterator i = m.keySet().iterator();
99          MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
100         assertEquals("bar", mnd.getImage());
101         assertEquals("bar", ((MethodNameDeclaration) i.next()).getImage());
102     }
103 
104 
105     @Test
106     public final void testOneParam() throws Throwable {
107         parseCode(ONE_PARAM);
108         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
109         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
110         MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
111         assertEquals("(String)", mnd.getParameterDisplaySignature());
112     }
113 
114     @Test
115     public final void testTwoParams() throws Throwable {
116         parseCode(TWO_PARAMS);
117         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
118         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
119         MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
120         assertEquals("(String,int)", mnd.getParameterDisplaySignature());
121     }
122 
123     @Test
124     public final void testNoParams() throws Throwable {
125         parseCode(NO_PARAMS);
126         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
127         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
128         MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
129         assertEquals("()", mnd.getParameterDisplaySignature());
130     }
131 
132     @Test
133     public final void testOneParamVararg() throws Throwable {
134     	parseCode15(ONE_PARAM_VARARG);
135         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
136         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
137         MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
138         assertEquals("(String...)", mnd.getParameterDisplaySignature());
139     }
140 
141     @Test
142     public final void testTwoParamsVararg() throws Throwable {
143     	parseCode15(TWO_PARAMS_VARARG);
144         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
145         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
146         MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
147         assertEquals("(String,String...)", mnd.getParameterDisplaySignature());
148     }
149 
150 
151     @Test
152     public final void testNestedClassDeclFound() throws Throwable {
153         parseCode(NESTED_CLASS_FOUND);
154         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
155         ClassScope c = (ClassScope) n.getScope();
156         Map m = c.getClassDeclarations();
157         ClassNameDeclaration cnd = (ClassNameDeclaration) m.keySet().iterator().next();
158         assertEquals("Buz", cnd.getImage());
159     }
160 
161     @Test
162     public final void testbuz() throws Throwable {
163         parseCode(METH);
164         //SymbolTableViewer st = new SymbolTableViewer();
165         //acu.jjtAccept(st, null);
166     }
167 
168     @Test
169     public void testMethodUsageSeen() {
170         parseCode(METHOD_USAGE_SEEN);
171         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
172         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
173         Iterator i = m.entrySet().iterator();
174         MethodNameDeclaration mnd;
175         Map.Entry entry;
176         
177         do {
178             entry = (Map.Entry) i.next();
179             mnd = (MethodNameDeclaration) entry.getKey();
180         } while (!mnd.getImage().equals("bar"));
181 
182         List usages = (List) entry.getValue();
183         assertEquals(1, usages.size());
184         assertEquals("bar", ((NameOccurrence) usages.get(0)).getImage());
185     }
186 
187     @Test
188     public void testMethodUsageSeenWithThis() {
189         parseCode(METHOD_USAGE_SEEN_WITH_THIS);
190         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
191         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
192         Iterator i = m.entrySet().iterator();
193         MethodNameDeclaration mnd;
194         Map.Entry entry;
195         
196         do {
197             entry = (Map.Entry) i.next();
198             mnd = (MethodNameDeclaration) entry.getKey();
199         } while (!mnd.getImage().equals("bar"));
200 
201         List usages = (List) entry.getValue();
202         assertEquals(1, usages.size());
203         assertEquals("bar", ((NameOccurrence) usages.get(0)).getImage());
204     }
205 
206     @Test
207     public void testMethodUsageSeen2() {
208         parseCode(METHOD_USAGE_SEEN2);
209         ASTClassOrInterfaceDeclaration n = acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
210         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
211         Iterator i = m.entrySet().iterator();
212         Map.Entry entry = (Map.Entry) i.next();
213         MethodNameDeclaration mnd = (MethodNameDeclaration) entry.getKey();
214         if (mnd.getNode().getBeginLine() == 2) {
215             List usages = (List) entry.getValue();
216             System.out.println(usages.size());
217             System.out.println(mnd);
218             mnd = (MethodNameDeclaration) i.next();
219         }
220     }
221 
222     private static final String METHOD_USAGE_SEEN2 =
223             "public class Foo {" + PMD.EOL +
224             " public void baz() {" + PMD.EOL +
225             "  baz(x, y);" + PMD.EOL +
226             " }" + PMD.EOL +
227             " private void baz(int x, int y) {}" + PMD.EOL +
228             "}";
229 
230 
231     private static final String METHOD_USAGE_SEEN =
232             "public class Foo {" + PMD.EOL +
233             " private void bar() {}" + PMD.EOL +
234             " public void buz() {" + PMD.EOL +
235             "  bar();" + PMD.EOL +
236             " }" + PMD.EOL +
237             "}";
238 
239     private static final String METHOD_USAGE_SEEN_WITH_THIS =
240             "public class Foo {" + PMD.EOL +
241             " private void bar() {}" + PMD.EOL +
242             " public void buz() {" + PMD.EOL +
243             "  this.bar();" + PMD.EOL +
244             " }" + PMD.EOL +
245             "}";
246 
247 
248     private static final String METH =
249             "public class Test {" + PMD.EOL +
250             "  static { " + PMD.EOL +
251             "   int y; " + PMD.EOL +
252             "  } " + PMD.EOL +
253             "  void bar(int x) {} " + PMD.EOL +
254             "  void baz(int x) {} " + PMD.EOL +
255             "}";
256 
257     private static final String NESTED_CLASS_FOUND =
258             "public class Test {" + PMD.EOL +
259             "  private class Buz {} " + PMD.EOL +
260             "}";
261 
262     private static final String ONE_PARAM =
263             "public class Test {" + PMD.EOL +
264             "  void bar(String x) {" + PMD.EOL +
265             "  }" + PMD.EOL +
266             "}";
267 
268     private static final String TWO_PARAMS =
269             "public class Test {" + PMD.EOL +
270             "  void bar(String x, int y) {" + PMD.EOL +
271             "  }" + PMD.EOL +
272             "}";
273 
274     private static final String NO_PARAMS =
275             "public class Test {" + PMD.EOL +
276             "  void bar() {" + PMD.EOL +
277             "  }" + PMD.EOL +
278             "}";
279 
280     private static final String ONE_PARAM_VARARG =
281             "public class Test {" + PMD.EOL +
282             "  void bar(String... s) {" + PMD.EOL +
283             "  }" + PMD.EOL +
284             "}";
285 
286     private static final String TWO_PARAMS_VARARG =
287             "public class Test {" + PMD.EOL +
288             "  void bar(String s1, String... s2) {" + PMD.EOL +
289             "  }" + PMD.EOL +
290             "}";
291 
292 
293     private static final String CLASS_NAME =
294             "public class Foo {}";
295 
296     private static final String METHOD_DECLARATIONS_RECORDED =
297             "public class Foo {" + PMD.EOL +
298             " private void bar() {}" + PMD.EOL +
299             "}";
300 
301     private static final String METHODS_WITH_DIFF_ARG =
302             "public class Foo {" + PMD.EOL +
303             " private void bar(String x) {}" + PMD.EOL +
304             " private void bar() {}" + PMD.EOL +
305             "}";
306 
307     private static final String ENUM_SCOPE =
308             "public enum Foo {" + PMD.EOL +
309             " HEAP(\"foo\");" + PMD.EOL +
310             " private final String fuz;" + PMD.EOL +
311             " public String getFuz() {" + PMD.EOL +
312             "  return fuz;" + PMD.EOL +
313             " }" + PMD.EOL +
314             "}";
315 
316     public static junit.framework.Test suite() {
317         return new junit.framework.JUnit4TestAdapter(ClassScopeTest.class);
318     }
319 }