View Javadoc

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