View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.lang.java.rule.design;
    5
    6   import net.sourceforge.pmd.lang.ast.Node;
    7   import net.sourceforge.pmd.lang.java.ast.ASTAnnotation;
    8   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody;
    9   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
    10  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
    11  import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
    12  import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
    13  import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
    14  import net.sourceforge.pmd.lang.java.ast.ASTResultType;
    15  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
    16
    17  public class UseSingletonRule extends AbstractJavaRule {
    18
    19      @Override
    20      public Object visit(ASTClassOrInterfaceBody decl, Object data) {
    21          if (decl.jjtGetParent() instanceof ASTClassOrInterfaceDeclaration) {
    22              ASTClassOrInterfaceDeclaration parent = (ASTClassOrInterfaceDeclaration) decl.jjtGetParent();
    23              if (parent.isAbstract() || parent.isInterface()) {
    24                  return super.visit(decl, data);
    25              }
    26              int i = decl.jjtGetNumChildren();
    27              int methodCount = 0;
    28              boolean isOK = false;
    29              while (i > 0) {
    30                  Node p = decl.jjtGetChild(--i);
    31                  if (p.jjtGetNumChildren() == 0) {
    32                      continue;
    33                  }
    34                  Node n = p.jjtGetChild(0);
    35                  if (n instanceof ASTAnnotation) {
    36                      n = p.jjtGetChild(1);
    37                  }
    38                  if (n instanceof ASTFieldDeclaration) {
    39                      if (!((ASTFieldDeclaration) n).isStatic()) {
    40                          isOK = true;
    41                          break;
    42                      }
    43                  } else if (n instanceof ASTConstructorDeclaration) {
    44                      if (((ASTConstructorDeclaration) n).isPrivate()) {
    45                          isOK = true;
    46                          break;
    47                      }
    48                  } else if (n instanceof ASTMethodDeclaration) {
    49                      ASTMethodDeclaration m = (ASTMethodDeclaration) n;
    50                      if (!m.isPrivate()) {
    51                          methodCount++;
    52                      }
    53                      if (!m.isStatic()) {
    54                          isOK = true;
    55                          break;
    56                      }
    57
    58                      // TODO use symbol table
    59                      if (m.getMethodName().equals("suite")) {
    60                          ASTResultType res = m.getResultType();
    61                          ASTClassOrInterfaceType c = res.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
    62                          if (c != null && c.hasImageEqualTo("Test")) {
    63                              isOK = true;
    64                              break;
    65                          }
    66                      }
    67
    68                  }
    69              }
    70              if (!isOK && methodCount > 0) {
    71                  addViolation(data, decl);
    72              }
    73          }
    74          return super.visit(decl, data);
    75      }
    76
    77  }