    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 }