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.entrySet().iterator();
138         Map.Entry entry = (Map.Entry) i.next();
139         
140         MethodNameDeclaration mnd = (MethodNameDeclaration) entry.getKey();
141         if (!mnd.getImage().equals("bar")) {
142             mnd = (MethodNameDeclaration) i.next();
143         }
144         List usages = (List) entry.getValue();
145         assertEquals(1, usages.size());
146         assertEquals("bar", ((NameOccurrence) usages.get(0)).getImage());
147     }
148 
149     public void testMethodUsageSeenWithThis() {
150         parseCode(METHOD_USAGE_SEEN_WITH_THIS);
151         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
152         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
153         Iterator i = m.entrySet().iterator();
154         Map.Entry entry = (Map.Entry) i.next();
155         MethodNameDeclaration mnd = (MethodNameDeclaration) entry.getKey();
156         if (!mnd.getImage().equals("bar")) {
157             mnd = (MethodNameDeclaration) i.next();
158         }
159         List usages = (List) entry.getValue();
160         assertEquals(1, usages.size());
161         assertEquals("bar", ((NameOccurrence) usages.get(0)).getImage());
162     }
163 
164     public void testMethodUsageSeen2() {
165         parseCode(METHOD_USAGE_SEEN2);
166         ASTClassOrInterfaceDeclaration n = (ASTClassOrInterfaceDeclaration) acu.findChildrenOfType(ASTClassOrInterfaceDeclaration.class).get(0);
167         Map m = ((ClassScope) n.getScope()).getMethodDeclarations();
168         Iterator i = m.entrySet().iterator();
169         Map.Entry entry = (Map.Entry) i.next();
170         MethodNameDeclaration mnd = (MethodNameDeclaration) entry.getKey();
171         if (mnd.getNode().getBeginLine() == 2) {
172             List usages = (List) entry.getValue();
173             System.out.println(usages.size());
174             System.out.println(mnd);
175             mnd = (MethodNameDeclaration) i.next();
176         }
177     }
178 
179     private static final String METHOD_USAGE_SEEN2 =
180             "public class Foo {" + PMD.EOL +
181             " public void baz() {" + PMD.EOL +
182             "  baz(x, y);" + PMD.EOL +
183             " }" + PMD.EOL +
184             " private void baz(int x, int y) {}" + PMD.EOL +
185             "}";
186 
187 
188     private static final String METHOD_USAGE_SEEN =
189             "public class Foo {" + PMD.EOL +
190             " private void bar() {}" + PMD.EOL +
191             " public void buz() {" + PMD.EOL +
192             "  bar();" + PMD.EOL +
193             " }" + PMD.EOL +
194             "}";
195 
196     private static final String METHOD_USAGE_SEEN_WITH_THIS =
197             "public class Foo {" + PMD.EOL +
198             " private void bar() {}" + PMD.EOL +
199             " public void buz() {" + PMD.EOL +
200             "  this.bar();" + PMD.EOL +
201             " }" + PMD.EOL +
202             "}";
203 
204 
205     private static final String METH =
206             "public class Test {" + PMD.EOL +
207             "  static { " + PMD.EOL +
208             "   int y; " + PMD.EOL +
209             "  } " + PMD.EOL +
210             "  void bar(int x) {} " + PMD.EOL +
211             "  void baz(int x) {} " + PMD.EOL +
212             "}";
213 
214     private static final String NESTED_CLASS_FOUND =
215             "public class Test {" + PMD.EOL +
216             "  private class Buz {} " + PMD.EOL +
217             "}";
218 
219     private static final String ONE_PARAM =
220             "public class Test {" + PMD.EOL +
221             "  void bar(String x) {" + PMD.EOL +
222             "  }" + PMD.EOL +
223             "}";
224 
225     private static final String TWO_PARAMS =
226             "public class Test {" + PMD.EOL +
227             "  void bar(String x, int y) {" + PMD.EOL +
228             "  }" + PMD.EOL +
229             "}";
230 
231     private static final String NO_PARAMS =
232             "public class Test {" + PMD.EOL +
233             "  void bar() {" + PMD.EOL +
234             "  }" + PMD.EOL +
235             "}";
236 
237 
238     private static final String CLASS_NAME =
239             "public class Foo {}";
240 
241     private static final String METHOD_DECLARATIONS_RECORDED =
242             "public class Foo {" + PMD.EOL +
243             " private void bar() {}" + PMD.EOL +
244             "}";
245 
246     private static final String METHODS_WITH_DIFF_ARG =
247             "public class Foo {" + PMD.EOL +
248             " private void bar(String x) {}" + PMD.EOL +
249             " private void bar() {}" + PMD.EOL +
250             "}";
251 
252     private static final String ENUM_SCOPE =
253             "public enum Foo {" + PMD.EOL +
254             " HEAP(\"foo\");" + PMD.EOL +
255             " private final String fuz;" + PMD.EOL +
256             " public String getFuz() {" + PMD.EOL +
257             "  return fuz;" + PMD.EOL +
258             " }" + PMD.EOL +
259             "}";
260 
261 
262 }