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 net.sourceforge.pmd.PMD;
7   import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
8   import net.sourceforge.pmd.ast.ASTMethodDeclaration;
9   import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
10  import net.sourceforge.pmd.ast.SimpleJavaNode;
11  import net.sourceforge.pmd.ast.SimpleNode;
12  import net.sourceforge.pmd.symboltable.ClassNameDeclaration;
13  import net.sourceforge.pmd.symboltable.ClassScope;
14  import net.sourceforge.pmd.symboltable.MethodNameDeclaration;
15  import net.sourceforge.pmd.symboltable.NameOccurrence;
16  import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
17  
18  import java.util.Iterator;
19  import java.util.List;
20  import java.util.Map;
21  
22  public class ClassScopeTest extends STBBaseTst {
23  
24      public void testEnumsClassScope() {
25          parseCode15(ENUM_SCOPE);
26      }
27  
28      // FIXME - these will break when this goes from Anonymous$1 to Foo$1
29      public void testAnonymousInnerClassName() {
30          ClassScope s = new ClassScope();
31          assertEquals("Anonymous$1", s.getClassName());
32          s = new ClassScope();
33          assertEquals("Anonymous$2", s.getClassName());
34      }
35  
36      public void testContains() {
37          ClassScope s = new ClassScope("Foo");
38          ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
39          node.setImage("bar");
40          s.addDeclaration(new VariableNameDeclaration(node));
41          assertTrue(s.getVariableDeclarations().keySet().iterator().hasNext());
42      }
43  
44      public void testCantContainsSuperToString() {
45          ClassScope s = new ClassScope("Foo");
46          SimpleNode node = new SimpleJavaNode(1);
47          node.setImage("super.toString");
48          assertFalse(s.contains(new NameOccurrence(node, node.getImage())));
49      }
50  
51      public void testContainsStaticVariablePrefixedWithClassName() {
52          ClassScope s = new ClassScope("Foo");
53          ASTVariableDeclaratorId node = new ASTVariableDeclaratorId(1);
54          node.setImage("X");
55          s.addDeclaration(new VariableNameDeclaration(node));
56  
57          SimpleNode node2 = new SimpleJavaNode(2);
58          node2.setImage("Foo.X");
59          assertTrue(s.contains(new NameOccurrence(node2, node2.getImage())));
60      }
61  
62      public void testClassName() {
63          parseCode(CLASS_NAME);
64          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
65          assertEquals("Foo", n.getScope().getEnclosingClassScope().getClassName());
66      }
67  
68      public void testMethodDeclarationRecorded() {
69          parseCode(METHOD_DECLARATIONS_RECORDED);
70          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
71          ClassScope s = (ClassScope) n.getScope();
72          Map m = s.getMethodDeclarations();
73          assertEquals(1, m.size());
74          MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
75          assertEquals("bar", mnd.getImage());
76          ASTMethodDeclaration node = (ASTMethodDeclaration) mnd.getNode().jjtGetParent();
77          assertTrue(node.isPrivate());
78      }
79  
80      public void testTwoMethodsSameNameDiffArgs() {
81          // TODO this won't work with String and java.lang.String
82          parseCode(METHODS_WITH_DIFF_ARG);
83          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
84          Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
85          assertEquals(2, m.size());
86          Iterator i = m.keySet().iterator();
87          MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
88          assertEquals("bar", mnd.getImage());
89          assertEquals("bar", ((MethodNameDeclaration) i.next()).getImage());
90      }
91  
92  
93      public final void testOneParams() throws Throwable {
94          parseCode(ONE_PARAM);
95          ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
96          Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
97          MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
98          assertEquals("(String)", mnd.getParameterDisplaySignature());
99      }
100 
101     public final void testTwoParams() throws Throwable {
102         parseCode(TWO_PARAMS);
103         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
104         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
105         MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
106         assertEquals("(String,int)", mnd.getParameterDisplaySignature());
107     }
108 
109     public final void testNoParams() throws Throwable {
110         parseCode(NO_PARAMS);
111         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
112         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
113         MethodNameDeclaration mnd = (MethodNameDeclaration) m.keySet().iterator().next();
114         assertEquals("()", mnd.getParameterDisplaySignature());
115     }
116 
117 
118     public final void testNestedClassDeclFound() throws Throwable {
119         parseCode(NESTED_CLASS_FOUND);
120         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
121         ClassScope c = (ClassScope) n.getScope();
122         Map m = c.getClassDeclarations();
123         ClassNameDeclaration cnd = (ClassNameDeclaration) m.keySet().iterator().next();
124         assertEquals("Buz", cnd.getImage());
125     }
126 
127     public final void testbuz() throws Throwable {
128         parseCode(METH);
129         //SymbolTableViewer st = new SymbolTableViewer();
130         //acu.jjtAccept(st, null);
131     }
132 
133     public void testMethodUsageSeen() {
134         parseCode(METHOD_USAGE_SEEN);
135         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
136         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
137         Iterator i = m.keySet().iterator();
138         MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
139         if (!mnd.getImage().equals("bar")) {
140             mnd = (MethodNameDeclaration) i.next();
141         }
142         List usages = (List) m.get(mnd);
143         assertEquals(1, usages.size());
144         assertEquals("bar", ((NameOccurrence) usages.get(0)).getImage());
145     }
146 
147     public void testMethodUsageSeenWithThis() {
148         parseCode(METHOD_USAGE_SEEN_WITH_THIS);
149         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
150         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
151         Iterator i = m.keySet().iterator();
152         MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
153         if (!mnd.getImage().equals("bar")) {
154             mnd = (MethodNameDeclaration) i.next();
155         }
156         List usages = (List) m.get(mnd);
157         assertEquals(1, usages.size());
158         assertEquals("bar", ((NameOccurrence) usages.get(0)).getImage());
159     }
160 
161     public void testMethodUsageSeen2() {
162         parseCode(METHOD_USAGE_SEEN2);
163         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
164         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
165         Iterator i = m.keySet().iterator();
166         MethodNameDeclaration mnd = (MethodNameDeclaration) i.next();
167         if (mnd.getNode().getBeginLine() == 2) {
168             List usages = (List) m.get(mnd);
169             System.out.println(usages.size());
170             System.out.println(mnd);
171             mnd = (MethodNameDeclaration) i.next();
172         }
173     }
174 
175     private static final String METHOD_USAGE_SEEN2 =
176             "public class Foo {" + PMD.EOL +
177             " public void baz() {" + PMD.EOL +
178             "  baz(x, y);" + PMD.EOL +
179             " }" + PMD.EOL +
180             " private void baz(int x, int y) {}" + PMD.EOL +
181             "}";
182 
183 
184     private static final String METHOD_USAGE_SEEN =
185             "public class Foo {" + PMD.EOL +
186             " private void bar() {}" + PMD.EOL +
187             " public void buz() {" + PMD.EOL +
188             "  bar();" + PMD.EOL +
189             " }" + PMD.EOL +
190             "}";
191 
192     private static final String METHOD_USAGE_SEEN_WITH_THIS =
193             "public class Foo {" + PMD.EOL +
194             " private void bar() {}" + PMD.EOL +
195             " public void buz() {" + PMD.EOL +
196             "  this.bar();" + PMD.EOL +
197             " }" + PMD.EOL +
198             "}";
199 
200 
201     private static final String METH =
202             "public class Test {" + PMD.EOL +
203             "  static { " + PMD.EOL +
204             "   int y; " + PMD.EOL +
205             "  } " + PMD.EOL +
206             "  void bar(int x) {} " + PMD.EOL +
207             "  void baz(int x) {} " + PMD.EOL +
208             "}";
209 
210     private static final String NESTED_CLASS_FOUND =
211             "public class Test {" + PMD.EOL +
212             "  private class Buz {} " + PMD.EOL +
213             "}";
214 
215     private static final String ONE_PARAM =
216             "public class Test {" + PMD.EOL +
217             "  void bar(String x) {" + PMD.EOL +
218             "  }" + PMD.EOL +
219             "}";
220 
221     private static final String TWO_PARAMS =
222             "public class Test {" + PMD.EOL +
223             "  void bar(String x, int y) {" + PMD.EOL +
224             "  }" + PMD.EOL +
225             "}";
226 
227     private static final String NO_PARAMS =
228             "public class Test {" + PMD.EOL +
229             "  void bar() {" + PMD.EOL +
230             "  }" + PMD.EOL +
231             "}";
232 
233 
234     private static final String CLASS_NAME =
235             "public class Foo {}";
236 
237     private static final String METHOD_DECLARATIONS_RECORDED =
238             "public class Foo {" + PMD.EOL +
239             " private void bar() {}" + PMD.EOL +
240             "}";
241 
242     private static final String METHODS_WITH_DIFF_ARG =
243             "public class Foo {" + PMD.EOL +
244             " private void bar(String x) {}" + PMD.EOL +
245             " private void bar() {}" + PMD.EOL +
246             "}";
247 
248     private static final String ENUM_SCOPE =
249             "public enum Foo {" + PMD.EOL +
250             " HEAP(\"foo\");" + PMD.EOL +
251             " private final String fuz;" + PMD.EOL +
252             " public String getFuz() {" + PMD.EOL +
253             "  return fuz;" + PMD.EOL +
254             " }" + PMD.EOL +
255             "}";
256 
257 
258 }